Update:
After C #5.0, await will throw an exception in canceling the task. For example, the following code is equivalent:
VaR src = new cancellationtokensource ();
SRC. cancelafter (100 );
Try
{
Await task. Factory. startnew () =>
{
Thread. Sleep (1000 );
SRC. Token. throwifcancellationrequested ();
}, SRC. Token );
}
Catch (exception ex)
{
Console. writeline (ex. GetType ());
}
The output will be:
System. operationcanceledexception
For task. Wait-related calls, the canceled operationcanceledexception exception will become taskcanceledexception and will be wrapped in aggresponexception.
VaR src = new cancellationtokensource ();
VaR task = task. Factory. startnew () =>
{
Thread. Sleep (1000 );
SRC. Token. throwifcancellationrequested ();
}, SRC. Token );
SRC. Cancel ();
Try
{
Task. Wait ();
}
Catch (aggresponexception AE)
{
Foreach (VAR ex in AE. innerexceptions)
Console. writeline (ex. GetType ());
}
Output:
System. Threading. Tasks. taskcanceledexception
Of course, you can manually throw an operationcanceledexception exception. Note that the cancellationtoken object is passed in the constructor.
VaR src = new cancellationtokensource ();
VaR task = task. Factory. startnew () =>
{
Thread. Sleep (500 );
Throw new operationcanceledexception ("Operation canceled", SRC. Token );
}, SRC. Token );
The same effect can be achieved.
For parallel and Plinq, operationcanceledexception is always thrown immediately after the parallel execution result is canceled.
In addition, the exception handling in parallel is significantly different from that in task. For details, refer to this article:. Net (C #) TPL: Parallel loop and Exception Handling for multiple tasks.
This example shows how to cancel an operation in the parallel class:
VaR opt = new paralleloptions ();
VaR src = new cancellationtokensource ();
Opt. cancellationtoken = SRC. Token;
Task. Factory. startnew () =>
{
Thread. Sleep (700 );
SRC. Cancel ();
});
Try
{
Parallel. For (1, 11, opt, I =>
{
Opt. cancellationtoken. throwifcancellationrequested ();
Thread. Sleep (500 );
Console. writeline ("iteration:" + I );
});
}
Catch (operationcanceledexception)
{
Console. writeline ("Operation canceled ");
}
Possible output:
Iteration: 1
Iteration: 7
Iteration: 5
Iteration: 3
Iteration: 2
Iteration: 6
Iteration: 8
Iteration: 4
Operation canceled
Similar to Plinq, you need to use the parallelenumerable. withcancellation method, and then pass the cancellationtoken.
VaR src = new cancellationtokensource (
Task. Factory. startnew () =>
{
Thread. Sleep (500 );
SRC. Cancel ();
});
Try
{
VaR res = enumerable. Range (1,100)
. Asparallel ()
. Withcancellation (SRC. Token)
. Select (I =>
{
Thread. Sleep (50 );
Return I;
});
Foreach (var I IN RES)
Console. writeline (I );
}
Catch (operationcanceledexception)
{
Console. writeline ("Operation canceled ");
}
Output:
Operation canceled