Similar to exceptions in for/foreach, any exceptions in the parallel loop end the entire loop, therefore, the entire loop will not be terminated immediately (if a thread is working for a long time and occurs after the throwifcancellationrequested method of cancellationtoken ).
Code:
Try
{
Parallel. For (0, 5, (I) =>
{
Throw new exception ("exception. Iterations: "+ I );
});
}
Catch (aggresponexception AE)
{
Foreach (VAR exp in AE. innerexceptions)
Console. writeline (exp. Message );
}
A subset of 0-4 will be output (it may also be all 0-4 output, because all five threads are completed quickly ).
Unlike parallel. For and foreach, parallel. InvokeAll tasks are always completed.And then wrap all exceptions in aggresponexception.
Let's look at this Code:
Try
{
Parallel. Invoke () =>{ throw new exception ("1 ");},
() => {Thread. Sleep (1500); throw new exception ("2 ");},
() => {Thread. Sleep (3000); throw new exception ("3 ");});
}
Catch (aggresponexception AE)
{
Foreach (VAR ex in AE. innerexceptions)
Console. writeline (ex. Message );
}
The result is output:
3
2
1
Task. waitall is similar to parallel. Invoke. Any (or multiple) task exception does not affect the execution of any other task.
Try
{
VaR T1 = task. Factory. startnew () =>
{
Thread. Sleep (700 );
Throw new exception ("1 ");
});
VaR t2 = task. Factory. startnew () =>
{
Thread. Sleep (1000 );
Throw new exception ("2 ");
});
Task. waitall (T1, T2 );
}
Catch (aggresponexception AE)
{
Foreach (VAR exp in AE. innerexceptions)
Console. writeline (exp. Message );
}
The output is as follows:
2
1
Both exceptions are in the innerexceptions attribute of aggresponexception.
For exceptions in task execution (rather than task. waitall), refer to this article:
. Net (C #) TPL: the task is not aware of exceptions and taskscheduler. unobservedtaskexception events.
For cancellation exceptions, refer:
. Net (C #) TPL: operationcanceledexception exception after the operation is canceled in task, parallel, and Plinq