簡體   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