I am handling all of my exceptions in Dispatcher.UnhandledException so I tried to direct exceptions coming from Tasks into this event. |I tried to send exception in the main thread.
task.ContinueWith((t) =>
{
....
if (t.Exception != null)
throw t.Exception;
}, TaskScheduler.FromCurrentSynchronizationContext());
but I can not take this exception in UnhandledException event , what is wrong with my solution?
More Info , the task and continuation is happening in a RealyCommand in WPF app using MVVM Light: here is my test view model, ExecuteTestCommand is running in UI thread
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
}
The implementation of the Task Parallel Library includes an exception handler which ensures (in most cases) that unhandled exceptions within a task do not result in the process terminating. This handler means your UnhandledException
event will never be called.
When you are not using async
/ await
, handling exceptions within a task is generally handled by the following process:
Faulted
status, and performs an appropriate action (such as directly reporting the error to a handler of some form). I developed the Rackspace Threading Library specifically for simplifying these scenarios. The Select
and Then
methods include complete handling for canceled and faulted antecedent tasks so you don't have to check the status of the antecedent in every continuation. The Select
and Then
methods which include a supportsErrors
parameter can be used to handle a faulted task (and not propagate the error to the parent). The Finally
methods can be used to handle a canceled or faulted task while still propagating the error to the parent.
If you can attach a handler to TaskScheduler.UnobservedTaskException you'll catch these exceptions too. However, note that this doesn't necessarily run on your main thread.
If you need to handle the exception on your main thread you could add code in the handler to marshal to the main thread (and then even re-throw).
I could not find any explanation why this happens?!!! but to solve my problem I used 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());
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.