Tuesday, 5 February 2013

Exception Handling with Parallel.Foreach

The .NET Framework's Parallel.Foreach is genius.  It eases the pain of making multiple tasks run in parallel.  It's just the ticket!  Oh, if only it were that simple.

What order do the tasks run in?  What when the parallel tasks throw exceptions?  How should that be handled?  When one task fails should the others be cancelled? Do we need to roll anything back?  What state updates are needed?  It soon becomes quite complex, quite quickly.

The project I'm working on right now has the following requirements:
  • It does not matter which order the tasks execute in;
  • There is no requirement to roll back the transaction should any individual task fail
  • If an exception is thrown, a SINGLE exception should be propagated upwards
The following achieves this, demonstrated in a console app, written in C#.


using System;
using System.Threading.Tasks;

namespace DavidBond.Net.ParallelTest
{
    /// <summary>
    /// Command line demonstration of Parallel.Foreach when Exceptions are thrown
    /// </summary>
    public class Program
    {
        /// <summary>
        /// Program entry point
        /// </summary>
        public static void Main()
        {
            Console.WriteLine("Program start.");

            // Create an array of task names
            var taskList = new[]
                {
                    "Task A",
                    "Task B throws Exception",
                    "Task C",
                    "Task D throws Exception"
                };

            // Try to run all the tasks in parallel
            try
            {
                // The following line is the equivalent of:
                //Parallel.ForEach(taskList, taskName => Execute(taskName));
                Parallel.ForEach(taskList, Execute);
            }
            // If there are any exceptions, wait until all tasks have completed
            catch (AggregateException aggregateException)
            {
                foreach (var innerException in aggregateException.InnerExceptions)
                {
                    Console.WriteLine("Exception occurred on task.  Exception message was [{0}]", innerException.Message);
                }
                // Uncomment the next line to escalate multiple underlying exceptions as a single exception.
                // throw new Exception("Not all tasks completed successfully.");
            }

            Console.WriteLine("Program complete.");
        }

        /// <summary>
        /// Writes the line "[taskName] ran successfully" to the console
        /// </summary>
        /// <exception cref="Exception">Thrown if the taskname contains the word "exception" (not case sensitive).</exception>
        /// <param name="taskName">The task name</param>
        private static void Execute(string taskName)
        {
            //
            if (taskName.ToLower().Contains("exception"))
            {
                throw new Exception(string.Format("Exception thrown by task [{0}]", taskName));
            }

            Console.WriteLine("{0} ran successfully", taskName);
        }
    }
}


DO NOT copy-and-paste this example if your situation varies considerably.
Props to http://www.manoli.net/csharpformat/ for the formatting!

15 comments:

  1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.
    I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging.
    If anyone wants to become a .Net developer learn from Dot Net Training in Chennai. or learn thru Dot Net Training in Chennai. Nowadays Dot Net has tons of job opportunities on various vertical industry.
    or Javascript Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry.

    ReplyDelete
  2. Your good knowledge and kindness in playing with all the pieces were very useful. I don’t know what I would have done if I had not encountered such a step like this.
    Best Devops online Training
    Online DevOps Certification Course - Gangboard

    ReplyDelete
  3. Your very own commitment to getting the message throughout came to be rather powerful and have consistently enabled employees just like me to arrive at their desired goals.
    Selenium training in Chennai
    Selenium training in Bangalore
    Selenium training in Pune
    Selenium Online training

    ReplyDelete
  4. Woah this blog is wonderful i like studying your posts. Keep up the great work! You understand, lots of persons are hunting around for this info, you could help them greatly.
    python Course in Pune
    python Course institute in Chennai
    python Training institute in Bangalore

    ReplyDelete
  5. Attend The Python training in bangalore From ExcelR. Practical Python training in bangalore Sessions With Assured Placement Support From Experienced Faculty. ExcelR Offers The Python training in bangalore.
    python training in bangalore

    ReplyDelete
  6. Whatever we gathered information from the blogs, we should implement that in practically then only we can understand that exact thing clearly, but it’s no need to do it, because you have explained the concepts very well. It was crystal clear, keep sharing..
    Java Training in Chennai
    Java Training in Coimbatore
    Java Training in Bangalore

    ReplyDelete