I am testing for using Task in my application. Now, I have done the fallowing:
var task = Task.Factory.StartNew(() => {
// long running process
throw new Exception("test"); // throwing TestException
});
task.ContinueWith(x => MyErrorHandler(task.Exception), TaskContinuationOptions.OnlyOnFaulted);
void MyErrorHandler(Exception error) {
MessageBox.Show(error.Message);
}
The idea is, that the long running process will executed and the user can working on without any blocking of the UI. If there was a problem (exception) it will be show, after the long running process has finished (in the normal case, there would be no exception)
Is this the correct way I have used it or does I have to do it on another way? Are there any problems, which I can get on this way and I don't see now?
This will work, as you're explicitly checking Task.Exception
, which will prevent the exception from being unobserved.
I would make a couple of recommendations here.
First, if this is truly a long running task, you might want to specify that:
var task = Task.Factory.StartNew(() => {
// long running process
throw new Exception("test"); // throwing TestException
}, TaskCreationOptions.LongRunning);
Second, you don't need the closure over task
:
// use x.Exception, since x is the task
task.ContinueWith(x => MyErrorHandler(x.Exception), TaskContinuationOptions.OnlyOnFaulted);
You may also want to have this run on the main thread, especially if you decide you want to use something more elaborate (in your UI) for reporting:
// This will work if MyErrorHandler uses a UI control, since it'll marshal back to the current synchronization context
task.ContinueWith(x => MyErrorHandler(x.Exception),
CancellationToken.None,
TaskContinuationOptions.OnlyOnFaulted,
TaskScheduler.FromCurrentSynchronizationContext());
(This is only required if you're going to use UI controls, etc, in your error handler.)
Also - If you're using .NET 4.5 or the async targetting pack for .NET 4, you can simplify this by using the new async
/await
support. If you flag your method as async
, you can do:
try
{
await Task.Factory.StartNew(() => {
// long running process
throw new Exception("test"); // throwing TestException
}, TaskCreationOptions.LongRunning);
}
catch(Exception error)
{
MyErrorHandler(error);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With