[英]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.