Thursday, March 12, 2015

Throwing Exceptions From Task


using System.Text;
using System.Threading.Tasks;

namespace ThrowingExceptionsFromTask
{

    public class MyCustomException : Exception
    {
        public MyCustomException() : base("custom exception was thrown") {}
        public MyCustomException(string message) : base(message) { }
        public MyCustomException(string message, Exception innerException) : base(message, innerException) { }
    }
}
//==============================================================

using System.Windows.Forms;
using System.Threading;

namespace ThrowingExceptionsFromTask
{
    public partial class Form1 : Form
    {
        ///When a task throws an exception, the joining or parent task can catch the 
        ///expection by calling the Task.Wait methods or accessing the Task.Result
        ///property.
        ///The call to Task.Wait method should be placed in a try block.
        ///
        ///Any exception throw by a task or nested task is wrapped or bundled (by the 
        ///Task infrastructure) into an AggregationException
        ///
        ///Example: if two nested tasks, each throws an exception, then these exceptions
        ///are wrap or bundled into a single exception called AggregationException.
        ///The joining or parent thread need to catch the AggregationException only, then
        ///extract from it, using the innerExceptions property, the exceptions thrown from
        ///the nested tasks
        //
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            TaskScheduler uits = TaskScheduler.FromCurrentSynchronizationContext();

            Task task1 = Task.Factory.StartNew(() =>
                {
                    //task1 may do some work here
                    //then starts child tasks
                    Task child1 = Task.Factory.StartNew(() =>
                        {
                            //will do some work
                            throw new MyCustomException("exception throwm from child1");
                        });

                    Task child2 = Task.Factory.StartNew(() =>
                        {
                            //will do some work that may cause an exception to be thrown
                            //simulating a throw exception
                            throw new MyCustomException("exception thrown from child2");
                        });
                    try
                    {
                        Task.WaitAll(child1, child2);//throws the Aggregation exception if any of the child
                                                    //task throws an exception
                               
                     
                    }
                    catch(AggregateException ae)
                    {
                        //child exceptions are wrapped in a single Aggregation exception
                        //use the InnerExceptions to sequence thru all the exception throw by child tasks
                        foreach (var ex in ae.InnerExceptions)
                        {
                            richTextBox1.AppendText(ex.GetType().Name + "\t" +ex.Message + "\n");
                        }
                    }
                },CancellationToken.None, TaskCreationOptions.None,uits);
        }
    }
}
///==================================================================
///All child tasks A,B,C,D throw an exception (choose some exceptions)
///Have task2 catch all the exceptions
///Hint: use the flatten method as shown below
///
/*
                foreach (Exception ex in ae.Flatten().InnerExceptions)
                {
                   display information about each exception ex
                }
 */
///

No comments:

Post a Comment