Created a simple program using Linqpad, where I am throwing an exception explicitly in the Parallel Foreach
loop, which ideally shall be caught in the caller as Aggregate Exception
, but when I explicitly throw the exception, it sometimes skip out few exceptions on random basis. I am not able to understand the behavior, anyone who can explain:
void Main()
{
try
{
var intList = new List<int> {1,2,3,4,5,6};
Parallel.ForEach(intList, i => Test1(i));
}
catch (AggregateException aggregateException)
{
foreach (var ex in aggregateException.Flatten().InnerExceptions)
{
ex.Message.Dump();
}
}
}
public void Test1(int i)
{
try
{
if (i % 2 != 0)
throw new Exception($"{i} - Odd value exception");
}
catch(Exception ex)
{
ex.Message.Dump();
throw;
}
}
public void Test2(int i)
{
if (i % 2 != 0)
throw new Exception($"{i} - Odd value exception");
}
public void Test3(int i)
{
try
{
if (i % 2 != 0)
throw new Exception($"{i} - Odd value exception");
}
catch(Exception ex)
{
ex.Message.Dump();
}
}
Details:
- There two versions of Test, one with explicit Try Catch and other without
- Both have similar inconsistent behavior to the extent that in Test1, even local try catch doesn't print the value
- There can be third version
Test3
which always work as exception is not explicitly thrown out of the parallel loop Dump
is a linqpad print call replace it byConsole.WriteLine
on the visual studio
There's an option define here, which collects all exceptions in a ConcurrentQueue
and throw them later as aggregated exception, but why the current code doesn't work as expected, I am not very sure. In this case we expect Output to be:
1 - Odd value exception
3 - Odd value exception
5 - Odd value exception
but some of them are randomly skipped, that too in a simple program, there are much more miss in a complex program, which do far more work