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

Zep*_*lin 2 .net c# asynchronous

根据我在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.

}
Run Code Online (Sandbox Code Playgroud)

因此,当长时间操作正在等待时,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.

}
Run Code Online (Sandbox Code Playgroud)

现在我等待我的DoSomethingAsync,以便我确信它不会更进一步,但问题是DoSomethingAsync()在等待LongOperation()时仍然向调用者发出手,并且我的Main方法恢复,我不知道不想因为它执行我的关键事情.

在异步逻辑中有一些我很想念的东西,那么"等待"其中包含异步方法的方法的意义何在?

我非常感谢我的问题的解决方案.

提前致谢.

Mar*_*ell 6

我认为这里的不匹配来自这些话:

如果任务太长,则使方法返回调用方.

await确实不是很长.这是异步的.如果某些东西需要很长时间但发生在本地CPU上,那么确定:它不太适合await(尽管你可以使用await机器作为将东西推送到工作线程的便捷方式,然后重新加入同步上下文线程什么时候完成).

但是,更好的例子是任务是外部的 ; 它可能是对SQL数据库,redis,或通过http,或通过某种IO层的另一个进程,或等待套接字数据的调用.请注意,即使与物理本地SSD存储通信也可能涉及长时间等待,至少通过CPU速度来衡量.当本地线程除了阻塞(等待回复)之外什么都不做的话,那么:在很多情况下,线程可以做得更好.

在客户端应用程序的情况下,那些"更好的东西"包括绘制UI和响应输入.对于服务器应用程序,那些"更好的东西"包括服务其他并发请求/加载.


以这种方式测量时:await作为编写需要来自外部源的数据的代码的有效方式,但不希望在数据到达时阻止当前线程.如果那不是您的情况:await可能不适合您.