Two of my colleagues (one from work and one from a user group) kindly pointed out to me that in my last post I omitted Continuation Tasks as a means of Error Handling for the TPL. As such, I will expand upon my last post with an example of handling errors via a Continuation Task.
Continuing where we left off last, the following code will utilize a Task Continuation to handle errors within Tasks.
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
// Initialize a Task which throws exception
var task = new Task(() =>
{
throw new Exception("It broke!");
});
// Configure the Continuation to only fire on error
task.ContinueWith(HandleError, TaskContinuationOptions.OnlyOnFaulted);
// Start the Task
task.Start();
}
Console.WriteLine("End of method reached");
Console.ReadKey();
}
private static void HandleError(Task task)
{
// The Task has an AggregateException
var agex = task.Exception;
if (agex != null)
{
// Output all actual Exceptions
foreach (var ex in agex.InnerExceptions)
{
Console.WriteLine(ex.Message);
}
}
}
And the result:
By using a Continuation Task which wraps our private method, HandleError (a method whose signature is effectively Action), we can effectively handle errors in a more elegant, less inline way. This allows centralizing Task handling logic in such cases as where you’d always want to log to a file or database, for example. Note that there is overhead in the complexity of this architecture – since we receive an AggregateException, we must loop through it to analyze our individual errors.
Sorry that I missed this in my first post!