繁体   English   中英

等待C#中的异步任务会发生什么?

[英]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实际上会触发一些异步行为,并将尚未完成的TaskMain Main做了什么? await它。 await是该方法如何表明“除非等待(通常是Task )完成,否则我无法做任何有用的事情”。

如果(如此处), Task尚未完成,则在此发生之前不会进一步进展(本身)。 如果这是方法中的第一个(必需的) await ,那么异步机制就会启动,注册一个延续并从Main返回。

它将不会超过任何await行,直到您作为await参数提供的Task (或其他await )完成,并且对于使用async机制的方法,直到该方法完全完成为止。

(我忽略了上面描述中的异常故事。这都是快乐的路径)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM