簡體   English   中英

async void事件處理程序 - 澄清?

[英]async void event handlers - clarification?

我試圖理解為什么不好做的原因:( 注意,這里的上下文是asp.net,無論是否無法跟蹤async void原因)

 public async void Page_Load(object sender, EventArgs e)
{
 ...
}

好吧,經過調查,我看到幾個不同的原因:

  • 達米安·愛德華茲在這里說:

    Web表單中的異步void事件處理程序僅在某些事件上受支持 ,如您所見,但實際上僅用於簡單的任務。 我們建議使用PageAsyncTask進行任何真正復雜的異步工作。

  • 列維在這里說:

    Web應用程序中的異步事件本質上就是奇怪的怪物。 Async void適用於火災和忘記編程模型。 這適用於Windows UI應用程序,因為應用程序一直存在,直到操作系統將其殺死,因此每當異步回調運行時,都保證它是可以與之交互的UI線程。 在Web應用程序中,由於請求是按定義瞬態的,因此該模型會崩潰。 如果異步回調恰好在請求完成后運行,則無法保證回調需要與之交互的數據結構仍處於良好狀態 因此,為什么火災和遺忘(以及異步無效)在Web應用程序中本身就是一個壞主意。

    也就是說,我們做瘋狂的體操試圖制作非常簡單的東西,如Page_Load工作,但支持這一點的代碼非常復雜,並且沒有經過基本場景之外的任何測試。 因此,如果您需要可靠性,我會堅持使用RegisterAsyncTask。

  • 這個網站說:

    我們知道我們的頁面生命周期有一組事件以預定義的順序觸發,下一個事件只有在最后一個事件完成時才會觸發。 因此,如果我們使用上述異步Page_Load方式,則在頁面生命周期事件中,一旦它到達異步,當前線程被釋放並且另一個線程被分配以異步完成任務,此事件將被觸發, 但ASP.NET無法執行生命周期中的下一個事件,因為Page_Load尚未完成 底層同步上下文等待,直到異步活動完成。 然后,只會觸發頁面生命周期的下一個事件,這使得整個過程僅處於同步模式。

  • 這個網站說

    當返回類型為void時,調用者可能會認為該方法在返回時已完成 這個問題可能以許多意想不到的方式出現。 在接口(或基類)上提供void返回方法的異步實現(或覆蓋)通常是錯誤的。 有些事件還假設他們的處理程序在返回時是完整的

我在這里看到非常不同 (非重疊)的原因。

題 :

什么是我們不應該寫public async void Page_Load(object sender, EventArgs e)的榮耀/真正的原因public async void Page_Load(object sender, EventArgs e)


嗯,我也不知道為什么它是一個問題,因為4.5確實使用了其目的是支持UseTaskFriendlySynchronizationContext

protected async void Page_Load(object sender, EventArgs e){...}

您鏈接的文章使原因非常清楚。 不要使用它,因為除了最基本的場景之外它不可靠。 我們可以在異步void方法中引入同步上下文,只有很多異步跟蹤技巧。 我們確實努力使這些基本方案工作,但我們的一般指導是避免使用它們,而是明確地注冊異步工作。

我還沒有驗證這一點 ,但我認為只要頁面有<%@ Page Async="true" ... %> ,就可以在ASP.NET 4.5 WebForms中使用async void Page_Load(...) <%@ Page Async="true" ... %>宣言。

我認為這是基於AspNetSynchronizationContext.OperationStarted實現,當在具有AspNetSynchronizationContext的線程上調用任何async void方法時調用AspNetSynchronizationContext 以下是相關評論:

 // If the caller tries to kick off an asynchronous operation while we are not
 // processing an async module, handler, or Page, we should prohibit the operation.

顯然, Async="true"頁面不違反此要求,並且在完成所有掛起操作(包括async void操作)之前,不會完成HTTP請求處理。

暫無
暫無

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

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