TaskScheduler.UnobservedTaskException never gets called

前端 未结 2 505
挽巷
挽巷 2020-12-31 07:14

Based on my research, I have learned the following:

  1. TaskScheduler.UnobservedTaskException must wait for the task to be garbage collected before th
相关标签:
2条回答
  • 2020-12-31 07:57

    To me, TaskScheduler.UnobservedTaskException at first gives a very wrong sense of security. It's really not worth much if it depends on Garbage Collection.

    I found the following solution, taken from this msdn article, to be much more reliable. It basically executes the continuation block (where you log the exception) only if there were unhandled exceptions in task1, and does not block UI execution.

    You might also want to flatten nested AggregateExceptions and perhaps create a extension method, as Reed Copsey depicted here.

    var task1 = Task.Factory.StartNew(() =>
    {
        throw new MyCustomException("Task1 faulted.");
    })
    .ContinueWith((t) =>
    {
        Console.WriteLine("I have observed a {0}",
            t.Exception.InnerException.GetType().Name);
    },
    TaskContinuationOptions.OnlyOnFaulted);
    
    0 讨论(0)
  • 2020-12-31 08:12

    Nathan,

    You're points are all true. Try the following:

    namespace ConsoleApplication1
    {
        using System;
        using System.Threading;
        using System.Threading.Tasks;
    
        class Program
        {
            static void Main(string[] args)
            {
                TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
    
                Task.Factory.StartNew(() =>
                {
                    Console.WriteLine("Task started.");
                    throw new Exception("Test Exception");
                });
    
                Thread.Sleep(1000);
                Console.WriteLine("First Collect");
                GC.Collect();
                GC.WaitForPendingFinalizers();
                Console.WriteLine("Waiting");
                Console.ReadKey();
            }
    
            static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
            {
                Console.WriteLine("UNOBSERVED EXCEPTION");
            }
        }
    }
    

    I have noticed that the debugger often "traps" the UnobservedTaskException event, causing it to not fire appropriately. Run this outside of the debugger, and it will print "UNOBSERVED EXCEPTION" every time prior to shutting down.

    0 讨论(0)
提交回复
热议问题