Reputation: 651
var tokenSource2 = new CancellationTokenSource();
CancellationToken ct = tokenSource2.Token;
var task = Task.Factory.StartNew(() => {
Thread.Sleep(4000);
Console.WriteLine("Done");
ct.ThrowIfCancellationRequested();
}, ct);
Thread.Sleep(1000); Look here! <---
tokenSource2.Cancel();
try
{
Console.WriteLine("Wait");
task.Wait();
}
catch (Exception e)
{
Console.WriteLine("Task was canceled");
}
I can't understand why if I comment this line all works ok and exception is catched in the main thread, but if I left this line exception is thrown in child thread on the line with ct.ThrowIfCancellationRequested(); We have one instance of the cancelation token in both cases. I'm a new in multithreadin, so I definetly miss somthing.
I tried the next code
static void Main(string[] args)
{
Thread.CurrentThread.Name = "Main";
Console.WriteLine("Name of the current thread is " + Thread.CurrentThread.Name);
var tokenSource2 = new CancellationTokenSource();
CancellationToken ct = tokenSource2.Token;
var task = Task.Factory.StartNew(() =>
{
Thread.Sleep(4000);
Console.WriteLine("Done");
try
{
ct.ThrowIfCancellationRequested(); // If I remove the try/catch here will be unhandled exception
}
catch (OperationCanceledException exp)
{
Console.WriteLine("Task was started then canceled");
}
}, ct);//ontinueWith(OnProcessImageEnded);
Thread.Sleep(1000);
tokenSource2.Cancel();
try
{
Console.WriteLine("Wait");
task.Wait();
}
catch (Exception e)
{
Console.WriteLine("Task was canceled");
}
Console.WriteLine("Task was finished");
Console.WriteLine(task.Status);
I process exception in the task's thread now, but it leads to Status of the task not to be set Canceled. I think it is because now the task can't catch the exception to process it. What is the right way?
I found http://msdn.microsoft.com/en-us/library/ee191553.aspx this example and it has the same problem! if we press on 'c' during execution it will throws unhandled exception when we try to rethrow by calling externalToken.ThrowIfCancellationRequested(); ... I'm confused at all. I'm using x64 Win 7, 4.5 .net framework
Upvotes: 2
Views: 184
Reputation: 7602
When you comment the line, chances are our Task is cancelled even before it is started. Hence you get the exception. When you add sleep - mostly it will be started, so cancellation happens within the task with your call to ThrowIfCancellationRequested
Upvotes: 2
Reputation: 78242
I'll defer to the documentation for this one.
Task.Wait Method
AggregateException
The Task was canceled -or- an exception was thrown during the execution of the Task. If the task was canceled, the AggregateException contains an OperationCanceledException in its InnerExceptions collection.
Essentially it is a race condition where if you make it to task.Wait
in time you win.
Upvotes: 0