来源:https://note.guoqianfan.com/2022/04/23/dont-use-async-void/
前言
之前都是在文档里看到:除了winform的事件可以使用async void
,其他情况下绝对不能使用async void
,而是要用async Task
。
对于这个规范,虽然不是很明白内里原因,但是一直遵守着。
直到这天看到了这篇博客:在 ASP.NET Core 中誤用 async void 竟引發了 502(Bad Gateway),说async void
里出现异常时会导致程序崩溃。研究测试了一番,终于明白原因。
摘录重点如下:
根據使用者提供的另一個線索「網站的某個功能壞了」,我們繼續往下追查,從程式碼當中我看到了一個近期新加的方法,它使用了 async void,沒錯,它使用了 async void,而且很不幸地它會發生 Exception,更慘的是這個 Exception 沒有被處理。
對 C# 非同步程式設計有了解的朋友,看到這邊應該大致上可以知道是發什麼問題了,async void 是建議應該避免使用的宣告方式,其中一個原因就是當 async void 方法發生 Exception 時無法從呼叫端捕獲,即使加了 try…catch… 也沒用,async void 方法就有點像是我們自己起了另一個 Thread 去執行程式一樣,執行的過程中如果發生 Exception 沒有去處理,Exception 就會一路被往上拋,最終在 AppDomain 層級被捕獲,然後我們的應用程式就掛了。
async-void-方法的异常无法被捕获
async void
方法抛出的异常无法被捕获,异常会被一直往上面抛,最终在AppDomain层级被捕获,然后程序就挂了。
示例代码如下:
[HttpGet]
public async void Get()
{
try
{
ThrowExceptionAsync();
}
catch (Exception ex