TPL and exception handling

That's all, there are a lot of questions on the above topic, but I think this is different enough to guarantee a new question. I have the following Task and the continuation for solving a number of Status tasks; TaskStatus.RanToCompletion , TaskStatus.Canceled and, of course, AggregateException through TaskStatus.Faulted . The code looks like

 Task<bool> asyncTask = Task.Factory.StartNew<bool>(() => asyncMethod(uiScheduler, token, someBoolean), token); asyncTask.ContinueWith(task => { // Check task status. switch (task.Status) { // Handle any exceptions to prevent UnobservedTaskException. case TaskStatus.RanToCompletion: if (asyncTask.Result) { // Do stuff... } break; case TaskStatus.Faulted: if (task.Exception != null) mainForm.progressRightLabelText = task.Exception.InnerException.Message; else mainForm.progressRightLabelText = "Operation failed!"; default: break; } } 

All of this works well, but I'm worried if I am doing it right, since there is the possibility of rejecting an AggregateException from a continuation - what then?

I do not want Wait on my asyncTask or continuation, as this will block the return to the user interface thread. To catch any exceptions thrown from a sequel cannot mean that I have to do something like this with confidence

 Task parentTask = Task.Factory.startNew(() => { Task<bool> asyncTask = Task.Factory.StartNew<bool>(() => asyncMethod(uiScheduler, token, someBoolean), token); Task continueTask = asyncTask.ContinueWith(task => { // My continuation stuff... } try { continueTask.Wait(); } catch(AggregateException aggEx) { // Some handling here... } }); 

will it work? What is the best thing here?

As always, thanks for your time.

+8
c # exception-handling continuations task-parallel-library
source share
2 answers

You can use the traditional try / catch in your delegates by watching for an AggregateException , or you can use certain continuations that will only be executed if the antecedent has worked using the TaskContinuationOptions.OnlyOnFaulted parameter. The latter approach allows you to define very clear work tasks. For example:

 Task myRootTask = ....; myRootTask.ContinueWith(rootAntecdent => { // this will only be executed if the antecedent completed successfully, no need to check for faults }, TaskContinuationOptions.OnlyOnRanToCompletion); myRootTask.ContinueWith(rootAntecedent => { // this will only be executed if the antecedent faulted, observe exception and handle accordingly }, TaskContinuationOptions.OnlyOnFaulted); 
+12
source share

Msdn has a fairly well-written "How to" on: here

You will notice that they simply use the try/catch(AggregateException ), then filter out the exception that they know how to handle in ae.Handle(lambda) , and stop the application if there are some left that are not being processed.

+2
source share

All Articles