Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle Task.Factory.StartNew exception?

I have some strange problem here. Exception thrown by Task always not handled independently how can I try to handle it.

I try this:

http://msdn.microsoft.com/en-us/library/dd997415%28v=vs.110%29.aspx

private class MyCustomException : Exception
{
     public MyCustomException(String message) : base(message)
     {
     }
}

public static void Main()
{
   var task1 = Task.Factory.StartNew(() =>
   {

      throw new MyCustomException("I'm bad, but not too bad!");
   });

   try
   {
      task1.Wait();
   }
   catch (AggregateException ae)
   {
       // Assume we know what's going on with this particular exception. 
       // Rethrow anything else. AggregateException.Handle provides 
       // another way to express this. See later example. 
       foreach (var e in ae.InnerExceptions)
       {
           if (e is MyCustomException)
           {
               Console.WriteLine(e.Message);
           }
           else
           {
               throw;
           }
       }

    }
    Console.Read();
}

this:

http://dotnetcodr.com/2014/02/11/exception-handling-in-the-net-task-parallel-library-with-c-the-basics/

this:

http://blogs.msdn.com/b/pfxteam/archive/2010/08/06/10046819.aspx

this:

var task = Task.Factory.StartNew(() => this.InitializeViewModel(myViewModel));
task.ContinueWith(o => MyErrorHandler(task.Exception), TaskContinuationOptions.OnlyOnFaulted);

and check a lot of other similar questions on StackOverflow. But It is always the same - exception is not handled. It is not handled on these primitive code snippets! I think it is some magic here... I work on .Net Framework 4.0

Meanwhile single way to handle exception that works for me is:

        Task.Factory.StartNew(() =>
        {
            try
            {
                //do something that thrown exception
            }
            catch (Exception)
            {

            }
        });
like image 714
monstr Avatar asked Apr 04 '14 07:04

monstr


2 Answers

If you run that example code in Visual Studio, you will indeed get the message MyCustomException was unhandled by user code and Visual Studio will break in that line.

That does not mean that your exception is really unhandled. It just means that, by default, Visual Studio breaks on exceptions which are not handled inside the Task. You can verify this by running your application without debugging (Ctrl-F5); you will note that your exception gets handled as expected.

This issue is described in more detail in the following SO question:

  • Stop visual studio from breaking on exception in Tasks
like image 175
Heinzi Avatar answered Oct 15 '22 10:10

Heinzi


Microsoft Visual Studio debugging facilities for managed code have an option "Just My Code". This option enabled forces debugger to break in immediately when an exception leaves user code (Task delegate in your example) and enters non-user code (TPL internal in your example). This feature was designed before introduction of TPL to make .NET applications debugging more comfortable with looking only at the code you have written and ignore other code, such as system calls. Just My Code hides non-user code so that it does not appear in the debugger windows. When you step, the debugger steps through any non-user code but does not stop in it.

But now in fact "Just My Code" feature interfere with TPL implementation.

There are four ways to deal with this issue:

  1. Run your code without debugging.
  2. Just ignoring of the Visual Studio debugger message about unhanded exception by continuation of program execution.
  3. Disabling of "Just My Code" option in the Microsoft Visual Studio. This variant is recommended by Microsoft guy Danny Shih from Parallel Computing Platform team (PFX Team) http://blogs.msdn.com/b/pfxteam/archive/2010/01/11/faq-the-debugger-does-not-correctly-handle-task-exceptions.aspx.
like image 35
ZarathustrA Avatar answered Oct 15 '22 10:10

ZarathustrA