Do a long process with a task and showing an exception if there is one

I am testing using Task in my application. Now I have done the following:

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 lengthy process will be done and the user can work without any blocking of the user interface. If there is a problem (exception), it will be shown after the end of the lengthy process (in the usual case, there will be no exception)

Did I use it correctly or do I need to do it differently? Are there any problems I might get along the way that I can't see now?

+3


source to share


1 answer


This will work since you are explicitly checking Task.Exception

what will prevent the exception from being hidden.

I would make a couple of recommendations here.

First, if this is a really long task, you can point out that:

var task = Task.Factory.StartNew(() => {
   // long running process
   throw new Exception("test"); // throwing TestException
}, TaskCreationOptions.LongRunning);

      

Second, you don't need to close over task

:

// use x.Exception, since x is the task
task.ContinueWith(x => MyErrorHandler(x.Exception), TaskContinuationOptions.OnlyOnFaulted);

      



You may also want to do this launch on the main thread, especially if you decide you want to use something more complex (in your interface) to post:

// 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 intend to use UI controls, etc., in an error handler.)

Also - if you are using .NET 4.5 or the .NET 4 asynchronous targeting package, you can simplify this by using the new support for async

/ await

. If you specify 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);
}

      

+7


source







All Articles