I'm following the example code here to learn about asynchronous tasks. I've modified the code to write some output of the task's work vs. the main work. The output will look like this:
I noticed that if I remove the Wait() call, the program runs the same except I can't catch the exception that's thrown when the task is canceled. Can someone explain what's going on behind the scenes requiring the Wait() in order to hit the catch block?
One warning, the Visual Studio debugger will erroneously stop on the Console.WriteLine(" - task work");
line with the message "OperationCanceledException was unhandled by user code". When that happens, just click Continue or hit F5 to see the rest of the program run. See http://blogs.msdn.com/b/pfxteam/archive/2010/01/11/9946736.aspx for details.
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
class Program
{
static void Main()
{
var tokenSource = new CancellationTokenSource();
var cancellationToken = tokenSource.Token;
// Delegate representing work that the task will do.
var workDelegate
= (Action)
(
() =>
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
// "If task has been cancelled, throw exception to return"
// Simulate task work
Console.WriteLine(" - task work"); //Visual Studio
//erroneously stops on exception here. Just continue (F5).
//See http://blogs.msdn.com/b/pfxteam/archive/2010/01/11/9946736.aspx
Thread.Sleep(100);
}
}
);
try
{
// Start the task
var task = Task.Factory.StartNew(workDelegate, cancellationToken);
// Simulate main work
for (var i = 0; i < 5; i++)
{
Console.WriteLine("main work");
Thread.Sleep(200);
}
// Cancel the task
tokenSource.Cancel();
// Why is this Wait() necessary to catch the exception?
// If I reomve it, the catch (below) is never hit,
//but the program runs as before.
task.Wait();
}
catch (AggregateException e)
{
Console.WriteLine(e.Message);
foreach (var innerException in e.InnerExceptions)
Console.WriteLine(innerException.Message);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}