[英]What happens when you await an asynchronous task in C#?
根据我在C#中的所有异步/等待教程中的理解,我得到了当我们定义异步方法时,它意味着我们可以在其中添加await关键字并将任务作为参数,以使方法返回到调用者,如果任务太长了。 然后,当任务完成时,该方法可以恢复。
public void MyMainMethod()
{
DoSomethingAsync();
KeepOnDoingOtherStuff();
}
public async Task DoSomethingAsync()
{
//Do whatever
await LongOperation();
// Rest of the method that is executed when the long operation is
//finished.
}
因此,当长时间操作正在等待时,DoSomething async将手提供给MainMethod并执行KeepOnDoingOtherStuff。 好
现在我的问题是我的DoSomethingAsync本身是否等待。 在这种情况下:
public async void MyMainMethod()
{
await DoSomethingAsync();
//Here is a critical method that I want to execute only when
//DoSomethingAsync is finished
CriticalStuff();
}
public async Task DoSomethingAsync()
{
//Do whatever
await LongOperation();
// Rest of the method that is executed when the long operation is
//finished.
}
现在我等待我的DoSomethingAsync,以便我确信它不会更进一步,但问题是DoSomethingAsync()在等待LongOperation()时仍然向调用者发出手,并且我的Main方法恢复,我不知道不想因为它执行我的关键事情。
在异步逻辑中有一些我很想念的东西,那么“等待”其中包含异步方法的方法的意义何在?
我非常感谢我的问题的解决方案。
提前致谢。
我认为这里的不匹配来自这些话:
如果任务太长,则使方法返回调用方。
await
的确不长 。 这是异步的 。 如果某些东西需要很长时间,但发生在本地CPU上,那么确定:它不太适合await
(尽管你可以使用await
机器作为一种方便的方式将东西推送到工作线程,然后重新加入同步 -上下文线程完成时)。
但是,更好的例子是任务是外部的 ; 它可能是对SQL数据库,redis,或通过http,或通过某种IO层的另一个进程,或等待套接字数据的调用。 请注意,即使与物理本地SSD存储通信也可能涉及长时间等待,至少通过CPU速度来衡量。 当本地线程除了阻塞 (等待回复) 之外什么都不做的话 ,那么:在很多情况下,线程可以做的事情要好得多。
在客户端应用程序的情况下,那些“更好的东西”包括绘制UI和响应输入。 对于服务器应用程序,那些“更好的东西”包括服务其他并发请求/加载。
以这种方式测量时: await
作为编写需要来自外部源的数据的代码的有效方式,但不希望在数据到达时阻止当前线程。 如果那不是您的情况: await
可能不适合您。
我正在讨论你的代码的这个变种:
public async void MyMainMethod()
{
await DoSomethingAsync();
//Here is a critical method that I want to execute only when
//DoSomethingAsync is finished
CriticalStuff();
}
public async Task DoSomethingAsync()
{
//Do whatever
await LongOperation();
// Rest of the method that is executed when the long operation is
//finished.
}
当DoSomethingAsync
返回时,它不会盲目地将控制权交还给调用方法。 它把它交给了一个Task
。 如果该方法实际上是同步完成的,那么它将返回已经完成的任务。 否则,如果该方法仍有工作要做,则Task
将运行,而不是(尚未)完成。
因此, DoSomethingAsync
实际上会触发一些异步行为,并将尚未完成的Task
给Main
。 Main
做了什么? await
它。 await
是该方法如何表明“除非等待(通常是Task
)完成,否则我无法做任何有用的事情”。
如果(如此处), Task
尚未完成,则在此发生之前不会进一步进展(本身)。 如果这是方法中的第一个(必需的) await
,那么异步机制就会启动,注册一个延续并从Main
返回。
它将不会超过任何await
行,直到您作为await
参数提供的Task
(或其他await
)完成,并且对于使用async
机制的方法,直到该方法完全完成为止。
(我忽略了上面描述中的异常故事。这都是快乐的路径)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.