2014-02-12 105 views
2

我的預期,我可以用這個模式:期待已久的任務不處理異常優雅

var task = Task.Run(() => Agent.GetUserType(Instance)); 
await task; 
string information = task.GetExceptionOrStatus(); // extension method 

當我的SQL Server未啓動 - 就像一個測試用例 - 我看到不同的是WCF服務拋出,我得到:
在Microsoft.Threading.Tasks.dll中發生類型'System.ServiceModel.FaultException'的異常,但未在用戶代碼中處理。
我的印象是我的代碼能夠從任務對象中提取錯誤。

我該如何做得更好?

回答

5

await將通過設計在該任務上傳播任何例外。

var task = Task.Run(() => Agent.GetUserType(Instance)); 
try 
{ 
    await task; 
} 
catch (Exception ex) 
{ 
    // TODO 
} 
string information = task.GetExceptionOrStatus(); // extension method 
+0

當我在.net 4.5中禁用ThrowUnobservedTaskExceptions時,是否可以不使用try-catch? – Gerard

+2

@Gerard:'ThrowUnobservedTaskExceptions'與此行爲無關。傳播例外是「異步」的設計方式;你有沒有想過的理由? –

+0

只需訪問任務結果而不用嘗試捕獲就很容易。例如。你的'INotifyTaskCompletion'通過'ContinueWith'和一個'PropertyChanged'回調優雅地處理異常。也許我應該看看'task.Exception.Handle'。另一方面,try-catch是明確的,這也是很好的。 – Gerard

1

你應該圍繞你的await task;在try/catch塊。如果發生Exception,它將拋出一個AggregateException,其中包含您的Task中發生的所有異常。

+1

一個期待已久的任務,實際上有其AggregateException '解開' 當你等待它。如果正在等待的任務出現FormatException錯誤,則可以直接捕獲FormatException。 –

+0

真的嗎?每當我在等待的方法上發現異常時,我都會看到'AggregateException'。也許我誤解了...... –

+1

'Task.Wait'或'Task.Result'會拋出AggregateException,但是等待它不會。實際上,即使在AggregateException中有多個異常,它也只會拋出第一個異常。要獲得底層聚合異常,需要在異常發生後直接從任務查詢它。請參閱[此問題](http://stackoverflow.com/questions/18314961/i-want-await-to-throw-aggregateexception-not-just-the-first-exception)以獲取更多信息。 –

2

如果你不想做await扔,你可以創建基於先前Task上一個新Task,不會失敗。喜歡的東西:

static async Task<T> IgnoreException<T>(this Task<T> task) 
{ 
    try 
    { 
     return await task; 
    } 
    catch 
    { 
     return default(T); 
    } 
} 

替代實現:

static Task<T> IgnoreException<T>(this Task<T> task) 
{ 
    return task.ContinueWith(t => t.Exception == null ? t.Result : default(T)); 
} 

用途則是這樣的:

await task.IgnoreException(); 
string information = task.GetExceptionOrStatus(); // extension method 
+0

嘿...也許..你使用這種方法嗎? Stephan Cleary將它與一種「On Error Resume Next」進行比較。 – Gerard

+0

@Gerard我會小心的。如果你總是用'GetExceptionOrStatus()'來關注它,顧名思義,它會讀取異常,那麼我認爲你很好。 – svick