Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TPL Exception handling

Tags:

c#-4.0

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.

like image 327
Sam Avatar asked Oct 25 '11 21:10

Sam


People also ask

How do you handle exceptions in TPL C#?

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.

How do you handle exceptions in parallel ForEach?

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.

What are the 3 blocks used to handle exception?

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.

Does await throw AggregateException?

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.


1 Answers

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! :]

like image 97
MoonKnight Avatar answered Oct 05 '22 09:10

MoonKnight