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
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!
great
ReplyDelete