Exceptions in tasks

A few examples show application behaviour when we have exception in task. Comments describe what happen in specific situations and how to cope with exceptions.

Example A.

        /// <summary>
        /// Method shows how exception from task is swallowed.
        /// </summary>
        internal static void TaksWithException()
        {
            //exception is swallowed
            //failure will not be visible as noone asks for result of the task
            //task is faulted
            var tA = new Task<int>(() =>
            {
                Console.WriteLine("Task A");
                throw new Exception("Unknown exception");
                return 1;
            });

            tA.ContinueWith((t) =>
            {
                if (t.IsFaulted)
                    Console.WriteLine("Task faulted.");
                else
                    Console.WriteLine("Task completed.");
            });

            tA.Start();
        }

Example B.

        /// <summary>
        /// Method shows how exception is not thrown until result is accessed.
        /// </summary>
        internal static void TaksWithException1()
        {
            //exception is unhandled
            //task is faulted
            //unhandled exception will be visible as we try to display result of the task.
            var tA = new Task<int>(() =>
            {
                Console.WriteLine("Task A");
                throw new Exception("Unknown exception");
                return 1;
            });

            tA.ContinueWith((t) =>
            {
                if (t.IsFaulted)
                    Console.WriteLine("Task faulted.");
                else
                    Console.WriteLine("Task completed.");
            });

            tA.Start();

            Console.WriteLine(tA.Result); //here exception is thrown
        }

Example C.

        /// <summary>
        /// Method shows how exception is handled in task body.
        /// </summary>
        internal static void TaksWithException2()
        {
            //exception is catched
            //task is not faulted
            //valid result is returned
            var tA = new Task<int>(() =>
            {
                try
                {
                    Console.WriteLine("Task A");
                    throw new Exception("Unknown exception");
                }
                catch (Exception)
                {
                    Console.WriteLine("Exception caught in catch.");
                }
                return 1;
            });

            tA.ContinueWith((t) =>
            {
                if (t.IsFaulted)
                    Console.WriteLine("Task faulted.");
                else
                    Console.WriteLine("Task completed.");
            });

            tA.Start();

            Console.WriteLine(tA.Result);
        }

Example D.

        /// <summary>
        /// Method shows how exception is handled when accessing the result in continuation method
        /// </summary>
        internal static void TaksWithException3()
        {
            //exception is not catched, but is not visible until task result is not accessed
            //task is faulted
            //AggregateException is catched when result is accessed
            var tA = new Task<int>(() =>
            {
                Console.WriteLine("Task A");
                throw new Exception("Unknown exception");
                return 1;
            });

            var tB = tA.ContinueWith((t) =>
            {
                if (t.IsFaulted)
                    Console.WriteLine("Task faulted.");
                else
                    Console.WriteLine("Task completed.");
            });

            tB.ContinueWith((t) =>
            {
                try
                {
                    Console.WriteLine(tA.Result);
                }
                catch (AggregateException ae)
                {
                    ae.Handle((e) =>
                    {
                        if (e is NullReferenceException)
                        {
                            Console.WriteLine("NullReferenceException in task handled when accessing the result");
                            return true;
                            }
                        else
                        {
                            Console.WriteLine("Other exception in task handled when accessing the result");
                            return true;
                        }
                    });
                }
                catch (Exception)
                {
                    Console.WriteLine("Exception in task handled when accessing the result");
                }
            });

            tA.Start();
        }

Example E.

        /// <summary>
        /// Method shows how to run appropriate continuation method when task has faulted.
        /// </summary>
        internal static void TaksWithException4()
        {
            //exception is not catched, but is not visible until task result is not accessed
            //task is faulted
            //appropriate continuation method is executed
            var tA = new Task<int>(() =>
            {
                Console.WriteLine("Task A");
                throw new Exception("Unknown exception");
                return 1;
            });

            tA.ContinueWith((t) =>
            {
                Console.WriteLine("Task completed.");
            }, TaskContinuationOptions.OnlyOnRanToCompletion);

            tA.ContinueWith((t) =>
            {
                Console.WriteLine("Task faulted.");
                if (t.Exception != null && t.Exception.InnerExceptions != null)
                {
                    foreach(var e in t.Exception.InnerExceptions)
                    {
                        Console.WriteLine(e.Message);
                    }
                }

            }, TaskContinuationOptions.OnlyOnFaulted);

            tA.Start();
        }
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s