[英]how to direct task exception to main thread?
我正在Dispatcher.UnhandledException中處理所有異常,因此我嘗試將來自Tasks的異常定向到此事件中。 |我試圖在主線程中發送異常。
task.ContinueWith((t) =>
{
....
if (t.Exception != null)
throw t.Exception;
}, TaskScheduler.FromCurrentSynchronizationContext());
但是我無法在UnhandledException事件中接受此異常,我的解決方案出了什么問題?
更多信息 ,該任務和延續發生在使用MVVM Light的WPF應用程序中的RealyCommand中:這是我的測試視圖模型, ExecuteTestCommand在UI線程中運行
class MainViewModel : ViewModelBase
{
public MainViewModel()
{
App.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
}
void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show("got it");
e.Handled = true;
}
#region TestCommand
private RelayCommand _testCommand;
public RelayCommand TestCommand
{
get
{
if (_testCommand == null)
_testCommand = new RelayCommand(ExecuteTestCommand, CanExecuteTestCommand);
return _testCommand;
}
}
private bool CanExecuteTestCommand()
{
return true;
}
private void ExecuteTestCommand()
{
// throw new Exception();
Task.Factory.StartNew(() =>
{
}).ContinueWith(t =>
{
App.Current.MainWindow.Title = "It is the main UI thread" + (App.Current.Dispatcher.Thread == System.Threading.Thread.CurrentThread).ToString();
throw new NotImplementedException();
}, TaskScheduler.FromCurrentSynchronizationContext());
}
#endregion
}
任務並行庫的實現包括一個異常處理程序,該異常處理程序確保(在大多數情況下)任務中未處理的異常不會導致進程終止。 此處理程序意味着將永遠不會調用您的UnhandledException
事件。
當您不使用async
/ await
,通常通過以下過程來處理任務中的異常:
Faulted
狀態的先前任務,並執行適當的操作(例如將錯誤直接報告給某種形式的處理程序)。 我開發了Rackspace線程庫,專門用於簡化這些情況。 Select
and Then
方法包括對已取消和有故障的前提任務的完整處理,因此您不必在每個后續操作中都檢查前提條件的狀態。 包含supportsErrors
參數的Select
and Then
方法可用於處理錯誤的任務(並且不會將錯誤傳播給父對象)。 Finally
方法可用於處理已取消或出現故障的任務,同時仍將錯誤傳播給父級。
如果您可以將處理程序附加到TaskScheduler.UnobservedTaskException,您也將捕獲這些異常。 但是,請注意,這不一定要在您的主線程上運行。
如果需要在主線程上處理異常,則可以在處理程序中添加代碼以封送處理到主線程(然后重新拋出)。
我找不到任何解釋為什么會發生這種情況?! 但是為了解決我的問題,我使用了Dispatcher.Invoke
private void ExecuteTestCommand()
{
// throw new Exception();
Task.Factory.StartNew(() =>
{
}).ContinueWith(t =>
{
if (t.Exception != null)
{
App.Current.Dispatcher.Invoke(new Action(() =>
{
throw t.Exception;
}));
return;
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.