[Figure 2 Exceptions from an Async Void Method Can’t Be Caught with Catch]
만약 AsyncTask 메서드가 Task를 반환하지 않는 async void였다면, 그것을 호출하는 CallAsyncTaskAwait 메서드에서는 Task 객체의 GetAwaiter()를 호출할 수 없어 결국 TaskAwatier.GetResult 메서드도 사용할 수 없어 예외가 먹히는 것입니다.
즉, async가 적용된 AsyncTask의 내부에서 예외가 try/catch로 처리되었지만 그것이 AsyncVoidMethodBuilder.SetException으로 보관되어 있었으므로 이를 TaskAwatier.GetResult() 메서드 내에서 구해 throw 처리를 할 수 있었던 것입니다.
[가이드라인]
1. Event Handler를 제외하고 async void의 사용은 피한다.
2. Console 프로젝트의 Main 메서드를 제외하고 호출 그래프의 상위를 모두 async로 바꾸며 blocking 코드를 넣지 않는다.
-> C# 7.1부터 Main 메서드에도 async Task를 적용할 수 있으므로 이제 "예외 없이 async로 바꾼다"로 변경해도 됩니다.
3. Context가 필요하지 않아면 ConfigureAwait(false)를 호출한다.
-> 다른 말로 하면 UI 요소를 건드리지 않는다면 ConfigureAwait(false)를 항상 호출하는 것이 권장된다고 여기시면 됩니다.
'C#' 카테고리의 다른 글
[Visual Studio] 네임스페이스에 형식 또는 네임스페이스 이름이 없습니다. 해결 방법 (0) | 2023.01.17 |
---|---|
DNS(Domain Name System) (0) | 2023.01.17 |
어셈블리 정보를 이용한 버전 관리, 자동 증가 (0) | 2023.01.17 |
Marshal.PtrToStructur (Returning pointers from unmanaged to managed code) (0) | 2023.01.17 |
관리되는 코드, 관리되지 않는 코드 (0) | 2023.01.17 |