I was just introduced to Tasks (TPL) yesterday, and so I tried to do a little sample project in order to develop an understanding of how to use them.
My sample proje
The comments above are correct in terms of the debugger and the options required to prevent the debugger breaking. However, the following should give you a better example of how to use continuations and indeed how to handle exceptions thrown from tasks within those continuations...
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 task = Task.Factory.StartNew (() => 7 / x);
try
{
task.Wait();
// OR.
int result = task.Result;
}
catch (AggregateException aggEx)
{
Console.WriteLine(aggEx.InnerException.Message);
}
Hope this helps.