我只是对C#的异步编程有一些基本的了解。据我了解,这段代码
statement1;
await statement2();
statement3;
statement4;
在逻辑上应等效于
statement1;
var awaiter = statement2().GetAwaiter();
awaiter.OnCompletion(() => {
awaiter.GetResult();
statement3;
statement4;
});
因此,如果代码中有await
语句,则以下所有语句仅在等待的任务完成后才开始执行。这似乎就像同步代码。该文档指出await
语句将导致执行返回给调用者,并在等待的任务完成后恢复执行。但是在下面的示例中,我无法完全理解它是如何工作的。
using System;
using System.Threading.Tasks;
namespace ThreadTesting
{
class Program
{
public static async Task Main(string[] args)
{
await DoSomething2(); // <------- B
Console.WriteLine("Test!"); // <------- C
Console.ReadKey(); // <------- D
}
public static async Task DoSomething2()
{
Console.WriteLine("Start DoSomething2");
var i = await DoSomething(); // <------ A
Console.WriteLine("End DoSomething2");
}
public static async Task<int> DoSomething()
{
Console.WriteLine("Start DoSomething1");
await Task.Delay(10000);
Console.WriteLine("Before returning from DoSomething1");
return 88;
}
}
}
输出是
Start DoSomething2
Start DoSomething1
Before returning from DoSomething1
End DoSomething2
Test!
让我们以语句A为例。在这里,它正在等待DoSomething()
。在等待时,执行逻辑从DoSomething2()
返回并返回到B。据我所知,在等待DoSomething2()
时,执行应该继续执行语句C和D(语句B)。但是结果表明,字符串"Test!"
仅在程序末尾打印。为什么会这样?我的理解正确吗?
参考方案
问题在于您的Main
返回Task
,因此它也完全是async
,将被“停止”。您的执行顺序将如下所示:
Main()
开始
Main进入await
运算符,并使用其余方法创建Task
。看来Main()
已停止,正在等待await
结果DoSomething2()
启动并写入控制台“ Start DoSomething2”
它到达下一个await
运算符,并使用其余的Task
方法创建另一个DoSomething()
DoSomething()
开始
它将写入控制台“ Start DoSomething1”
获取awat
运算符,并使用Task
方法的其余部分创建一个DoSomething()
,等待延迟。
此Task
完成之后(经过延迟),DoSomething()
向控制台写入“从DoSomething1返回之前”,并返回88。
在Task
中创建的DoSomething2()
完成该方法的其余部分(将88分配给i
并向控制台写入“从DoSomething1返回之前”)
在Task
中创建的Main()
完成,写“ Test!”。进行控制台。
因此,“测试!”最终是因为您的Main()
返回Task
。如果您想要这种行为,则期望将Task
交换为void
:
public static async void Main(string[] args)
{
...
}
然后,当到达await
运算符时,Main()
不会等待Task()
完成,并将继续执行。
我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…
Mongo汇总 - javascript我的收藏中有以下文件{ "_id": ObjectId("54490b8104f7142f22ecc97f"), "title": "Sample1", "slug": "samplenews", "cat": …
如何在Wiremock中为JUNIT匹配精确的json - java我正在使用Wiremock在Spring启动应用程序中模拟Junit的REST服务。我的问题是,我无法匹配多个匹配模式。 Junit.javaStringValuePattern pattern = WireMock.matching(".*"); givenThat(post(urlEqualTo("/softwares…
多重处理:map与map_async - python使用map和map_async有什么区别?将列表中的项目分配给4个进程后,它们是否运行相同的功能?因此,假设两者都在异步和并行运行是错误的吗?def f(x): return 2*x p=Pool(4) l=[1,2,3,4] out1=p.map(f,l) #vs out2=p.map_async(f,l) python大神给出的解决方案 将作业映射到流程…
jQuery DataTable TableTool在IE和Firefox中不起作用 - c#我在MVC4 ASP.NET Web应用程序中使用Jquery DataTable TableTool。导出到Excel和PDF可以与Chrome完美配合。但是不能在IE和FireFox中使用。我的代码如下 dom: 'T<"clear">lfrtip', tableTools: { "sSwfP…