我通常編寫web服務器,起初我認爲必須有連續的方法鏈返回任務,所以填滿堆棧可能會詢問數據庫是否完成。c#如何處理異步void
最近我看到WPF的代碼,這不類似的東西:
public async void Execute(object parameter)
{
await ExecuteAsync(parameter);
}
在事件處理函數調用。用戶界面似乎是響應式的,所以我想它確實有效。它是如何工作的?這是如何轉化爲aspnet的?
我通常編寫web服務器,起初我認爲必須有連續的方法鏈返回任務,所以填滿堆棧可能會詢問數據庫是否完成。c#如何處理異步void
最近我看到WPF的代碼,這不類似的東西:
public async void Execute(object parameter)
{
await ExecuteAsync(parameter);
}
在事件處理函數調用。用戶界面似乎是響應式的,所以我想它確實有效。它是如何工作的?這是如何轉化爲aspnet的?
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));
}
我解釋async void
方法的工作原理 - 以及爲什麼他們應該避免 - 在我Best Practices in Asynchronous Programming文章。
async void
與async Task
具有相同的語義,例外情況除外。一個async void
方法將在該方法開始時捕獲當前的SynchronizationContext
,並且該方法的任何異常都將被捕獲並直接在該捕獲的上下文中引發。在最常見的情況下,這會導致應用程序級異常,通常是崩潰。有些人稱async void
方法爲「即忘即忘」,但由於其特殊的行爲,我更喜歡「火災和碰撞」。 :)
「避免異步無效」是一般準則,有一個值得注意的例外:事件處理程序(或邏輯上是事件處理程序的項目,如ICommand.Execute
實現)。
它是如何工作的?這是如何轉化爲aspnet的?
它的工作方式與其他async
方法一樣。主要的平臺區別在於當async
方法完成時,UI線程不需要知道。 ASP.NET需要知道它知道何時發送請求,但UI不需要知道方法何時完成。所以async void
的作品。這仍然是最好的避免,因爲調用代碼通常確實需要知道它何時完成。
當我不等待任務時會發生什麼? – user2029276
@ user2029276 asp.net子系統不知道該任務,並可能在該功能完成執行之前拆除該網站的應用程序域,導致您告訴該功能做的工作丟失並且從未完成。你可以在WPF中擺脫這種情況的原因是你的AppDomain在用戶使用這個程序的時候不會被隨意拆除,只要程序運行在AppDomain上。一個不活躍的用戶在一個asp.net網站上可能會有一個AppDomain被拆除,甚至沒有注意到它發生。 –