2013-10-18 93 views
1

我們有一個WPF應用程序,其中:TPL在Windows XP

private void SomeHandler(object sender, RoutedEventArgs e) 
{ 
    Task.Factory.StartNew(LoadItems).ContinueWith(t => 
    { 
    //cache items to, for instance, db 
    }, TaskContinuationOptions.NotOnFaulted); 
} 

private void LoadItems() 
{ 
//sometimes it throws an exception 
//this is expected 
throw new FormatException("blablabla"); 
} 

所以,一般來說,我們使用這個處理程序嘗試當存在數據緩存中的數據。 如果它不存在,那麼我們會得到一個Formatexception。我們不關心結果,只是「失火而忘記」的策略。

我最近有兩個來自客戶端的日誌文件,我看到FormatException被傳播到CurrentDomain_UnhandledException處理程序。所有客戶端都使用.Net 4.0的Windows XP。

所以問題是爲什麼這樣呢?是否按設計?

回答

2

這是.NET 4.0上的預期行爲。如果有一個Task發生異常,並且該例外從未被觀察到,則在Task完成時重新排除該異常。

如果您安裝了.Net 4.5,並且想要獲得此行爲(例如,用於測試),請使用add <ThrowUnobservedTaskExceptions> to app.config

如果你想確保未觀察到Task異常不被再次拋出,即使是在.NET 4.0中,可以使用TaskScheduler.UnobservedTaskException

TaskScheduler.UnobservedTaskException += (o, args) => args.SetObserved(); 

但我認爲,在這裏最好的選擇是明確地觀察異常。你可以做到這一點通過移除NotOnFaulted選項,並檢查Exception屬性來代替:記住,如果延續任務也拋出從未觀察到的異常,你就直背在同一條船上

Task.Factory.StartNew(LoadItems).ContinueWith(t => 
{ 
    if (t.Exception == null) 
    { 
    //cache items to, for instance, db 
    } 
}); 
+0

軸承:) – shambulator

+0

這是一個有趣的突破性變化...感謝您解釋 –

+0

還有一個有趣的觀察,因爲在終結器中引發異常,即使安裝了UnhandledException處理程序,應用程序也會終止。這是我在我的應用程序的日誌中看到的。 –