避免非同步無效
-
唯一可以安全使用
async void的地方是事件處理程式。請考慮以下程式碼:private async Task<bool> SomeFuncAsync() { ... await ... } public void button1_Click(object sender, EventArgs e) { var result = SomeFuncAsync().Result; SomeOtherFunc(); }一旦
async呼叫完成,它將等待SynchronizationContext變為可用。但是,事件處理程式在等待SomeFuncAsync方法完成時保持SynchronizationContext; 從而導致迴圈等待(死鎖)。要解決這個問題,我們需要將事件處理程式修改為:
public async void button1_Click(object sender, EventArgs e) { var result = await SomeFuncAsync(); SomeOtherFunc(); } -
任何從
async void方法丟擲的異常將直接在async void方法啟動時啟用的SynchronizationContext上引發。private async void SomeFuncAsync() { throw new InvalidOperationException(); } public void SomeOtherFunc() { try { SomeFuncAsync(); } catch (Exception ex) { Console.WriteLine(ex); throw; } }這個例外永遠不會被
SomeOtherFunc中的 catch 塊捕獲。 -
async void方法沒有提供一種簡單的方法來通知他們已經完成的呼叫程式碼 -
async void方法很難測試。MSTest 非同步測試支援僅適用於返回Task或Task<T>的async方法。