Использование обработчика UnobservedTaskException в dotnetcoreapp2.0 - PullRequest
0 голосов
/ 22 декабря 2018

Следующий код при запуске в приложении netcoreapp2.0, похоже, не выдает UnobservedTaskException

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

namespace ConsoleApp3 {

    class Program {

        public static void Main(string[] args) {

            TaskScheduler.UnobservedTaskException += (s, e) => {
                /// Try to crash the application - we wanna nail unobserved exceptions dead.
                /// Unfortunately, this code never seems to run.
                Console.WriteLine("UnobservedTaskException thrown.");
                throw e.Exception; 
            };

            var t = Task.Run(() => {
                throw new NotImplementedException();
            });

            while (!t.IsFaulted)
                Thread.Sleep(1);

            t = null;
            Console.WriteLine("Task is faulted.");

            GC.Collect();
            GC.WaitForPendingFinalizers();
            Console.ReadKey();
        }

    }
}

Вот файл проекта.Как получить обработчик UnobservedTaskException для запуска?

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <LangVersion>7.3</LangVersion>
  </PropertyGroup>

</Project>

В других статьях stackoverflow я видел совет использовать следующий фрагмент кода в файле проекта, но он работает только для .net framework4.0+ проектов.Если есть эквивалент для файла проекта .netcore, это может быть то, что мне нужно знать.

<runtime> 
    <ThrowUnobservedTaskExceptions enabled="true"/> 
</runtime> 

Ответы [ 2 ]

0 голосов
/ 19 марта 2019

У меня была такая же проблема.Просто попробуйте запустить его в режиме RELEASE .Я протестировал его и он работает с консольным приложением .net core версии 2.2.

internal class Program
{
    private static void Main(string[] args)
    {
        // REMEMBER TO RUN IN RELEASE MODE

        var handler = new EventHandler<UnobservedTaskExceptionEventArgs>(Unobserved);
        TaskScheduler.UnobservedTaskException += handler;

        Task.Run(() => { Console.WriteLine("task 1"); throw new Exception("TASK 1 EXCEPTION"); });
        Task.Run(() => { Console.WriteLine("task 2"); throw new Exception("TASK 2 EXCEPTION"); });

        Thread.Sleep(1000);

        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();

        Thread.Sleep(1000);

        Console.ReadKey();
    }

    private static void Unobserved(object o, UnobservedTaskExceptionEventArgs e)
    {
        e.SetObserved(); // optional
        foreach (var ex in e.Exception.InnerExceptions)
        {
            Console.WriteLine(ex.Message);
        }
    }
}
0 голосов
/ 22 декабря 2018

Ответов пока нет, но я нахожу это немного интригующим.Я смотрю на исходный код на GitHub.Единственное место, где вызывается обработчик события, это метод PublishUnobservedTaskException в классе TaskScheduler.

Единственное место, которое вызывается PublishUnobservedTaskException, это финализатор TaskExceptionHolder.Однако есть несколько условий, которые должны быть выполнены, прежде чем он вызовет PublishUnobservedTaskException, как вы можете видеть в этом исходном коде.

Я включил отладку исходного кода .NET , но я получаю версию TaskExceptionHolder, отличную от той, что есть на GitHub, и она явно не соответствует точкам останова, которые я пытаюсь создать.Так что я не могу точно подтвердить, почему ему не звонят, и у меня закончилось время этим вечером.

Возможно, стоит даже создать проблему для этого в GitHub .

...