2017-01-16 52 views
3

我通常編寫web服務器,起初我認爲必須有連續的方法鏈返回任務,所以填滿堆棧可能會詢問數據庫是否完成。c#如何處理異步void

最近我看到WPF的代碼,這不類似的東西:

public async void Execute(object parameter) 
    { 
     await ExecuteAsync(parameter); 
    } 

在事件處理函數調用。用戶界面似乎是響應式的,所以我想它確實有效。它是如何工作的?這是如何轉化爲aspnet的?

回答

6

Async void僅用於事件處理程序/委託可比性。 Execute是一個事件回調,可能來自DelegateCommand或類似的事件。

它的工作方式是,它的處理方式與您返回Task的函數完全相同,但調用者從未在返回的任務上調用await

在ASP.NET你可能永遠不會使用異步無效,改爲使用控制器,公開方法返回一個Task<ActionResult>,使用HostingEnviorment.QueueBackgroundWorkItem,或者使用在在一個情況,其中Page.RegisterAsyncTask你會使用async void包裹起來功能在正常的桌面編程中。

public void Page_Load(object sender, EventArgs e) 
{ 
    RegisterAsyncTask(new PageAsyncTask(LoadSomeData)); 
} 
+0

當我不等待任務時會發生什麼? – user2029276

+1

@ user2029276 asp.net子系統不知道該任務,並可能在該功能完成執行之前拆除該網站的應用程序域,導致您告訴該功能做的工作丟失並且從未完成。你可以在WPF中擺脫這種情況的原因是你的AppDomain在用戶使用這個程序的時候不會被隨意拆除,只要程序運行在AppDomain上。一個不活躍的用戶在一個asp.net網站上可能會有一個AppDomain被拆除,甚至沒有注意到它發生。 –

7

我解釋async void方法的工作原理 - 以及爲什麼他們應該避免 - 在我Best Practices in Asynchronous Programming文章。

async voidasync Task具有相同的語義,例外情況除外。一個async void方法將在該方法開始時捕獲當前的SynchronizationContext,並且該方法的任何異常都將被捕獲並直接在該捕獲的上下文中引發。在最常見的情況下,這會導致應用程序級異常,通常是崩潰。有些人稱async void方法爲「即忘即忘」,但由於其特殊的行爲,我更喜歡「火災和碰撞」。 :)

「避免異步無效」是一般準則,有一個值得注意的例外:事件處理程序(或邏輯上是事件處理程序的項目,如ICommand.Execute實現)。

它是如何工作的?這是如何轉化爲aspnet的?

它的工作方式與其他async方法一樣。主要的平臺區別在於當async方法完成時,UI線程不需要知道。 ASP.NET需要知道它知道何時發送請求,但UI不需要知道方法何時完成。所以async void的作品。這仍然是最好的避免,因爲調用代碼通常確實需要知道它何時完成。