Monthly Archives: June 2017

Exception Handling in Task Parallel Library

Typically when you are using Task parallel library in .NET, the thread on which task would get executed would be different thread , so if you have  you have try catch blocked wrapped for the Task call and have wait on the task then you can catch the exception but it will not show the original exception which was raised. Take for e.g. below

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Worker worker = new Worker();
                var task = Task.Factory.StartNew(worker.DoWork);
                task.Wait();
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.GetType());
            }
            Console.ReadLine();
        }
    }

    public class Worker
    {
        public void DoWork()
        {
            throw new Exception("Testing TPL Library Exception Handling");
        }
    }

In the above case the output would be

One or more errors occurred.
System.AggregateException

To propagate all the exceptions back to the calling thread, the Task infrastructure wraps them in an AggregateException instance. The AggregateException exception has an InnerExceptions property that can be enumerated to examine all the original exceptions that were thrown, and handle (or not handle) each one individually. You can also handle the original exceptions by using the System.AggregateException.Handle method.
Even if only one exception is thrown, it is still wrapped in an AggregateException exception

So we will modify the code to accommodate the AggregateException

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Worker worker = new Worker();
                var task = Task.Factory.StartNew(worker.DoWork);
                task.Wait();
            }
            catch (AggregateException ex)
            {
                foreach (var e in ex.InnerExceptions)
                {
                    Console.WriteLine(e.Message);
                    Console.WriteLine(e.GetType());
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.GetType());
            }
            Console.ReadLine();
        }
    }

    public class Worker
    {
        public void DoWork()
        {
            throw new Exception("Testing TPL Library Exception Handling");
        }
    }

 

In this case output would be
Testing TPL Library Exception Handling
System.Exception

HTH

Advertisements