Monday, December 26, 2016

How to handle exception in Parallel.For and Parallel.Foreach loop? – Task Parallel Library


In my previous article, I explained about Parallel.For andParallel.Foreach loop in detail. In this article I will explain, how to handle exception in Parallel.For and Parallel.Foreach loop.

Parallel.For and Parallel.Foreach methods doesn’t provide any special mechanism to handle exception thrown from parallel loops. We can catch unhandled exceptions using try catch block inside parallel loop. When you add any try catch block to catch exception in parallel loop, there is possibility that the same exception may throw by multiple threads in parallel. So we need to wrap try catch block inside parallel loop and also on method from where we call parallel loop to catch all types of exceptions. See below example.

Code –
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Concurrent;
namespace ParallelFor
{
class Program
{
static void Main(string[] args)
{
try
{
DoSomeWork();
}
catch (AggregateException ex)
{
//loop through all the exception
foreach(Exception e in ex.InnerExceptions)
{
if (e is ArgumentException)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(e.Message);
}
else
throw e;
}
}
Console.ReadLine();
}
public static void DoSomeWork()
{
//ConcurrentQueue allows to queue item from multiple threads.
ConcurrentQueue<Exception> exceptionQueue = new ConcurrentQueue<Exception>();
Parallel.For(0, 100, (i) =>
{
try
{
if (i == 20 || i == 30 || i == 40)
throw new ArgumentException();
Console.Write("{0}, ", i);
}
catch (Exception e)
{
//Adding all the exceptions thrown from multiple thread in queue
exceptionQueue.Enqueue(e);
}
});
//throw all the exception as AggregateException after loop completes
if (exceptionQueue.Count > 0) throw new AggregateException(exceptionQueue);
}
}
}
view raw Program.cs hosted with ❤ by GitHub

Output –


As you can see in above example, all exception thrown from Parallel.For loop is captured as ArgumentException and added to ConcurrentQueue from multiple threads. If parallel loop has any exception occurred, then we need to iterate all the exception to get exception message.

References –

See also –