2013-02-15 105 views
3

根據documentationHttpResponseException由Web API自動處理,並且Web API應該僅將HttpResponseMessage返回給客戶端並與其對應的HttpStatusCode。它通常會起作用。未處理的異常在拋出異步時崩潰Web API服務無效操作

但是,如果我們從標有async動作扔HttpResponseException那麼這是行不通的,並HttpResponseException只是崩潰的全程服務的東西,如「例外是由用戶代碼未處理」的消息。添加自定義異常過濾器不能解決問題,因爲Web API不會捕獲HttpResponseException消息。

更新1 我進一步的調查,並已發現,只要你添加await修改到一個動作,然後從這個動作每一個未處理的異常崩潰的Web API服務。並沒有涉及ExceptionFilterAttributes,Web API只是不執行它們。你甚至不必從真正的異步代碼中拋出異常,只需將async添加到操作中就可以使每個異常都完全無法處理。

這裏,這個工程確定,除了可以通過一些異常過濾器捕獲:

public void Test() 
{ 
    throw new Exception("Hello"); 
} 

,這將導致服務崩潰:

public async void Test() 
{ 
    throw new Exception("Hello"); 
} 

更新2 嗯,看起來像一切工作正常,如果我們將void更改爲某種實際類型,此處:

public async Task<int> Test() 
{ 
    throw new Exception("Hello"); 
} 

因此,看起來像從async void未處理的異常導致服務崩潰,但async Task<SomeType>工作正常,異常過濾器捕獲除了HttpResponseExceptionHttpResponseException正確處理Web API的一切。

看起來我剛纔跟自己說過,但是找到爲什麼async void動作中的異常無法正確處理會很有意思?

回答

3

避免async void的原因之一就是這些方法進行錯誤處理的方式。

async void方法旨在用作事件處理程序。 全部其他async方法應該是async Taskasync Task<T>async等效的同步void返回方法是async Task,而不是async void

async返回任務對象的方法將在該任務對象上放置異常。 async void方法沒有任務對象,因此它們通過在async void方法開始執行時激活的SynchronizationContext上引發異常來處理異常。這模擬事件處理程序的行爲。

+0

好的,謝謝,很好的回答!我忘了驗證'異步任務'情況順便說一句。 – 2013-02-15 07:21:25