簡體   English   中英

在僅返回 Task 的異步方法上使用 await

[英]Using await on async method that returns only Task

在我的 ASP.NET 核心應用程序中,我創建了幾個(十幾個)方法,其形式為

public async Task DoStuff() 
{ 
   // ...
}

所以,沒有返回類型。

后來,我意識到我不小心忘記在調用者方法中到處都包含 await (顯然沒有 async 關鍵字,因為異步“僵屍病毒”還沒有傳播那么遠)。

在執行期間,沒有任何不良后果。

問題是,當這種情況發生時,Visual Studio 也不會生成任何警告消息,我問自己,在這種情況下是否真的存在忽略等待的危險 我知道 await 應該自然地應用於每個 async 方法,但是當調用者實際上沒有要使用的返回值時,我真的不明白這背后的原因。 也許有捕捉異常的東西?

我還沒有找到任何明確的答案,因為一般性聲明是“簡單地包含等待”。 信不信由你,這個我相對較新的異步/等待的東西,不時地反復咬我。

在執行期間,沒有任何不良后果。

我不同意。 生成的代碼很危險。 ASP.NET pre-Core 能夠檢測到類似情況並引發異常(“異步模塊或處理程序已完成,而異步操作仍處於掛起狀態”)。 由於技術原因,ASP.NET 內核無法檢測到這種情況,因此您不會遇到“安全網”異常,但情況本身仍然很糟糕。

問題是,當這種事情發生時,Visual Studio 也不會生成任何警告消息

您沒有得到CS4014(“因為沒有等待此調用,所以在調用完成之前繼續執行當前方法。考慮將 await 運算符應用於調用結果。”)

在這種情況下,實際上是否存在忽略等待的危險? 我知道 await 應該自然地應用於每個 async 方法,但是當調用者實際上沒有要使用的返回值時,我真的不明白這背后的原因。 也許有捕捉異常的東西?

是的,有危險。 Task (即使沒有結果類型)用於兩件事:讓調用者知道操作何時完成,以及讓調用者檢測該操作的異常。

所以,一個問題是異常被默默地吞沒了。 更具體地說, async方法中的異常由async state 機器捕獲並放置在返回的Task上,然后將其忽略。

如果我自己處理上述方法中的異常(未正確等待的異常),那么我們可以說一切都很好嗎?

不,因為另一個問題仍然存在:調用者不知道異步操作何時完成。 在 ASP.NET 中了解這一點尤為重要,因為在操作完成之前不應發送結果。 ASP.NET 上的任何“即發即棄”代碼都存在於請求/響應生命周期之外 即,它是請求外部代碼。

我 go 在我的博客上詳細介紹了為什么請求外部代碼是危險的 總之,您的 ASP.NET 處理程序可能完成得太快,在這種情況下,請求外部代碼可能會“丟失”。 至少,在發送響應時,它所做的任何事情都不會完成; 並且在定期關閉的情況下(例如,滾動升級),它可能根本無法完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM