http://msdn.microsoft.com/en-us/library/dd997415.aspx
Per the article referenced above I am trying to handle exceptions in a continuatin task. The example I am citing in the above article is this:
var task1 = Task.Factory.StartNew(() =>
{
throw new MyCustomException("Task1 faulted.");
})
.ContinueWith((t) =>
{
Console.WriteLine("I have observed a {0}",
t.Exception.InnerException.GetType().Name);
},
TaskContinuationOptions.OnlyOnFaulted);
My code is:
Task<string> task = Task<string>.Factory.StartNew(() => process.StartTask(this));
task.ContinueWith(CloseDialog, TaskContinuationOptions.OnlyOnFaulted);
In StartTask, I throw an error just like the example. My expectation is that CloseDialog will execute and I can examine task.Exception within that method as shown by the example. However when I throw the exception I the code simply stops with an unhandled exception. Should I be using a try/catch block? If so, where? By the way, I want my continuation task (CloseDialog) to ALWAYS run. I'm just using .OnlyOnFaulted because that is what is shown in the example.
Tasks Module Example Public Sub Main() Dim task1 = Task. Run(Sub() Throw New CustomException("This exception is expected!")) Try task1. Wait() Catch ae As AggregateException ' Call the Handle method to handle the custom exception, ' otherwise rethrow the exception. ae.
For and Parallel. ForEach overloads do not have any special mechanism to handle exceptions that might be thrown. In this respect, they resemble regular for and foreach loops ( For and For Each in Visual Basic); an unhandled exception causes the loop to terminate as soon as all currently running iterations finish.
The "catch" block is used to handle the exception. It must be preceded by try block which means we can't use catch block alone. It can be followed by finally block later. The "finally" block is used to execute the necessary code of the program.
When using await, it's going to unwrap the first exception and return it, that's why we don't hit the catch (AggregateException e) line. But if we use something like the below code sample, we catch the AggregateException , note that it's not a good idea since we're blocking the running thread.
A continuation can find out if an exception was thrown by the antecedent Task
by the antecedent task's exception property. The following prints the results of a NullReferenceException
to the console
Task task1 = Task.Factory.StartNew (() => { throw null; });
Task task2 = task1.ContinueWith (ant => Console.Write(ant.Exception());
If task1
throws an exception and this exception is not captured/queried by the continuation it is considered unhandled and the application dies. With continuations it is enough to establish the result of the task via the Status
keyword
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;
}
}
If you don't use continuations you either have to wait on the task in a try
/catch
block or query a task's Result
in a try
/catch
block
int x = 0;
Task<int> task = Task.Factory.StartNew (() => 7 / x);
try
{
task.Wait();
// OR.
int result = task.Result;
}
catch (AggregateException aggEx)
{
Console.WriteLine(aggEx.InnerException.Message);
}
Hope this help even if it is a bit late and you know all there is by now! :]
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