Avoid async void

RiCo 技術農場
RiCosNote
Published in
6 min readJul 18, 2020

--

我們的系統基於分散式設計,可以在多台VM或Container上執行,

理當應用程式可以跨執行緒、VM、實體Server、Process或Container都不是問題,

非同步開發當然也是需要的,async/await語法糖提供一個較簡單的非同步演算法,

你撰寫一個非同步方法,就如同是在寫同步方法一樣,但執行過程卻和同步方法不同,

另外,async非同步程式設計並不等於多執行緒(這問題是最多開發人員會問我的),

c#發展至今,TAP 是在 .NET Framework 4 中引進,它讓非同步設計比以前更簡單,

也是非同步設計的建議方法(.Net4.5新增async 和 await),避免再繼續使用EAP和APM進行非同步設計,

但要記住,如果你不知道自己在寫什麼,你可能會遇到更多非預期問題,

甚至改回同步並損失改善Web系統吞吐量和回應性的機會,因為非同步開發還是滿有挑戰的。

我最近 Code review 看了滿多async void,來簡單說說為什麼應該避免async void。

async void只用於非同步事件例外處理(也是唯一例外),其他情況都不應該寫async void 方法(使用async Task取代),

async void有不同錯誤處理組合語義,它打破非同步方法捕捉例外協定(例外可能被排程要回復時拋出),

另外,async void也難以測試,你無法簡單確認該方法何時結束(無法被等待,射後不理的處理),

雖然可以透過SynchronizationContext來解決,

但這是一個我認為比較複雜的解決方案,

我們只要改寫為async Task或移除async就可輕鬆解決,何樂而不為呢?

下面程式碼無法正確catch exception

[Route("TestVoid"), HttpGet]public void TestVoid(){try{ThrowExceptionAsync();}catch (Exception){// The exception is never caught here!throw;}}private async void ThrowExceptionAsync(){throw new InvalidOperationException();}
中斷點無效

解決方法如同我上面提到的,

移除ThrowExceptionAsync方法的async比較簡單(別自己控制SynchronizationContext),

就能正常catch exception。

— 工商實戰課程和組合包 —

SQL Server 實戰效能調校系列 & 深入淺出EF Core3 組合包
https://hiskio.com/packages/W1wVgzyzq

SQL Server 實戰效能調校系列 & K8S 開發人員篇 組合包
https://hiskio.com/packages/8LwvD3Rgj

SQL Server Love Linux系列 & 效能調校四部曲 全組合包
https://hiskio.com/packages/MQRm2Dr0d

SQL Server Love Linux|全系列組合包
https://hiskio.com/packages/ZzraD6Rg8

SQL Server實戰效能調校|四部曲組合包
https://hiskio.com/packages/gOyLLvyA1

深入淺出Entity Framework Core 3
優惠碼: 13L27JE
https://hiskio.com/courses/365?promo_code=13L27JE

Kubernetes從0到1 | 開發人員篇
優惠碼: LG2XNRE
https://hiskio.com/courses/338?promo_code=LG2XNRE

第一部曲: TSQL優化
優惠碼: VE9Q0QE
https://hiskio.com/courses/267?promo_code=VE9Q0QE

第二部曲: 資料表索引
優惠碼: QE86JVG
https://hiskio.com/courses/270?promo_code=QE86JVG

第三部曲: 執行計畫
優惠碼: LEOVMQG
https://hiskio.com/courses/271?promo_code=LEOVMQG

第四部曲:縱橫交易
優惠碼: WG45OQ3
https://hiskio.com/courses/272?promo_code=WG45OQ3

SQL Server Love Linux|基礎篇
優惠碼:J3MZO5E
https://hiskio.com/courses/273?promo_code=J3MZO5E

SQL Server Love Linux | 管理篇
優惠碼 : JGZLNR3
https://hiskio.com/courses/280?promo_code=JGZLNR3

SQL Server Love Linux | 效能篇
優惠碼 : NEXL8YE
https://hiskio.com/courses/288?promo_code=NEXL8YE

射茶包|SQL Server連線問題排除實戰
優惠碼 : 6G6NZNG
https://hiskio.com/courses/268?promo_code=6G6NZNG

射茶包|挽救毀損資料庫實戰
優惠碼 : 13KOXPE
https://hiskio.com/courses/269?promo_code=13KOXPE

Reference:

Task asynchronous programming model

Task-based asynchronous pattern

Asynchronous programming with async and await

Async/Await — Best Practices in Asynchronous Programming

Async in depth

Asynchronous programming

--

--

RiCo 技術農場
RiCosNote

分享工作上實戰經驗,如SQL Server,NetCore,C#,WEBApi,Kafka,Azure…等,Architect,Software Engineer, Technical Manger,Writer and Speaker