Почему обработчик события UnobservedTaskException не запускается для задачи, которая выдает исключение?

1

У меня есть ниже тестовая программа, которая устанавливает UnobservedTaskException, однако метод OnTaskException никогда не выполняется. Есть идеи?

ПРИМЕЧАНИЕ.

Если я удалю "цикл цикла", тогда все будет работать так, как ожидалось.

static void Main()
{
    SetupUnobservedTaskExceptionHandling();

    Task.Factory.StartNew(() =>
    {
        var counter = 5;
        for (; counter > 0; counter--)
        {
            Console.WriteLine(counter);
            Thread.Sleep(1000);
        }
        throw new InvalidCastException("I threw up!");
    });

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

private static void SetupUnobservedTaskExceptionHandling()
{
    TaskScheduler.UnobservedTaskException += OnTaskException;
}

private static void OnTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
    Console.WriteLine("Error!" + e.Exception);
    e.SetObserved();
}
  • 1
    Это не дубликат глобального обработчика исключений TAP , это просто ошибка.
  • 1
    @ I3arnon: принятый ответ на этот вопрос объясняет, что событие не запускается, если задача не собрана. Это в значительной степени объясняет, почему цикл в этом вопросе задерживает исключение настолько, чтобы пропустить вызов GC.Collect .
Показать ещё 3 комментария
Теги:
task-parallel-library
unobserved-exception

1 ответ

2
Лучший ответ

Вы не дожидаетесь завершения выполнения задачи. Это означает, что ваше приложение закончится до того, как задача выдает исключение.

Если вы просто добавите Thread.Sleep и пусть задача Thread.Sleep исключение, вы будете уведомлены:

private static void Main()
{
    SetupUnobservedTaskExceptionHandling();

    Task.Factory.StartNew(() =>
    {
        var counter = 5;
        for (; counter > 0; counter--)
        {
            Console.WriteLine(counter);
            Thread.Sleep(1000);
        }
        throw new InvalidCastException("I threw up!");
    });

    Thread.Sleep(10000);

    GC.Collect();
    GC.WaitForPendingFinalizers();
    Console.ReadLine();
}
  • 0
    очень интересно. Можете ли вы объяснить, почему удаление цикла for также исправляет это? Я очень смущен этим поведением.
  • 0
    @MaYaN Это не цикл for ... это Thread.Sleep(1000); внутри него. Когда вы удаляете его, задание выдается сразу перед вызовом GC.Collect
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню