非同步void
方法的異常處理
在使用微軟的非同步CTP進行非同步程式設計時,理解非同步void
方法的異常處理行為至關重要。考慮以下場景:
<code class="language-csharp">public async void Foo() { var x = await DoSomethingAsync(); } public void DoFoo() { try { Foo(); } catch (ProtocolException ex) { // 异常将永远不会被捕获。 } }</code>
問題是:在呼叫方法DoFoo
中能否捕捉非同步方法Foo
中拋出的異常?
答案:可以(但有前提條件)
異常確實會冒泡到呼叫程式碼,但前提是您需要await
或Wait()
Foo
的呼叫。修改程式碼如下:
<code class="language-csharp">public async Task Foo() { var x = await DoSomethingAsync(); } public async void DoFoo() { try { await Foo(); } catch (ProtocolException ex) { // 异常将被捕获,因为它是一个异步方法。 } } public void DoFoo() { try { Foo().Wait(); } catch (ProtocolException ex) { // 异常将被捕获,因为调用被等待。 } }</code>
這樣就能在呼叫程式碼中進行異常處理。
然而,需要注意的是,非同步程式設計領域的權威人士Stephen Cleary警告:
此外,使用「非同步
void
方法具有不同的錯誤處理語義。當從非同步Task
或非同步Task<T>
方法拋出異常時,該異常會被捕獲並放置在Task
物件上。對於異步void
方法,沒有Task
對象,因此從異步void
方法拋出的任何異常都將直接在啟動異步void
方法時活動的SynchronizationContext
上引發。
等待任務完成可能會阻塞應用程序,如果.NET決定同步執行該方法的話。 Wait()
以上是Async Void 方法中拋出的異常可以透過呼叫方法捕獲嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!