我試圖了解在某些情況下跳過 async/await 是否有優化,或者這是否會導致陷阱。下面的代碼是由示例組成的,但它有助于簡化我的問題和理解。
假設我有以下代碼:
public async Task<string> CreateRandomString()
{
var myTitleTask = GetTitle();
var randomString = CreateRandomString();
var myTitle = await myTitleTask;
return myTitle randomString;
}
private async Task<string> GetTitle()
{
return await GetTitleFromWebServiceAsync();
}
可以像這樣從方法中洗掉async/ :awaitGetTitle()
public async Task<string> CreateRandomString()
{
var myTitleTask = GetTitle();
var randomString = CreateRandomString();
var myTitle = await myTitleTask;
return myTitle randomString;
}
private Task<string> GetTitle()
{
return GetTitleFromWebServiceAsync();
}
這是否優化了任何東西,因為我們盡可能長時間地延遲等待TaskfromGetTitle()并因此做其他作業,直到我們等待,或者這是否會導致任何問題?
在第二個示例中,我認為這是更優化和更好的方法,但只是想確保我沒有陷入任何陷阱。請問對此有何看法或意見?
uj5u.com熱心網友回復:
這是否優化了任何東西,因為我們盡可能長時間地延遲等待來自 GetTitle() 的任務,因此在我們等待之前做其他作業,或者這是否會導致任何問題?
好吧,我不打算進入基準測驗,但這是我有時會做的。如果我需要“掃描”檔案夾中的影像或某些檔案。我在目錄的 foreach 回圈中啟動任務并列舉它們以獲取相關檔案,退出回圈并等待它們全部,即并行查看每個檔案夾。而不是Task t = Task.Run(() => foo());我們總是可以按照您的建議做,只需回傳任務而不是等待它,然后在最后await myTask或await myTasks
還有其他用途,例如在微服務架構中,您可能希望“觸發并忘記”創建的訂單,例如電子郵件服務、通知服務等......處理所有這些,然后您將成功回傳給用戶。就像您在亞馬遜上下訂單一樣,您只會感謝您下訂單。對于像您這樣的順序函式,我看不出在第 3 行或第 5 行等待它有什么好處。這真的取決于代碼。
uj5u.com熱心網友回復:
可以像這樣從 GetTitle() 方法中洗掉 async/await:
是的,這樣做是完全安全的。
這是否優化了任何東西,因為我們盡可能長時間地延遲等待來自 GetTitle() 的任務,因此在我們等待之前做其他作業,或者這是否會導致任何問題?
它們是直接等價的,跳過 async/await 應該稍微高效一些,但我希望差異很小。如果您對實際數字感興趣,我建議您進行一些基準測驗。
uj5u.com熱心網友回復:
是的,當您發現自己只在 return 陳述句中使用 await 時,從方法簽名中洗掉 async 關鍵字可以優化性能和包大小。C# 編譯器將每個標有 async 的方法轉換為繼承 IAsyncStateMachine 的單獨類!它基本上將異步方法分為幾個同步部分(2個等待= 3個部分)并根據類狀態執行每個部分。因此,將方法修改為類后,最終的包大小會增加 100 位元組的開銷(現在通常是一個非常小的問題)。當存在 await 關鍵字時,還存在運行時必須切換執行緒的性能開銷。因此,在可能的情況下回傳任務而不等待它會導致更少的背景關系切換,這是相當昂貴的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/490584.html
