避免非同步無效
-
唯一可以安全使用
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
方法。