C# 对于引发异常的任务,为什么未触发UnobservedTaskException事件处理程序?

C# 对于引发异常的任务,为什么未触发UnobservedTaskException事件处理程序?,c#,.net,task-parallel-library,unobserved-exception,C#,.net,Task Parallel Library,Unobserved Exception,我有下面的测试程序,它设置了UnobservedTaskeException,但是从未执行过OnTaskeException方法。有什么想法吗 注意: 如果我删除“for循环”,那么一切都会按预期工作 static void Main() { SetupUnobservedTaskExceptionHandling(); Task.Factory.StartNew(() => { var counter = 5; for (; co

我有下面的测试程序,它设置了UnobservedTaskeException,但是从未执行过OnTaskeException方法。有什么想法吗

注意

如果我删除“for循环”,那么一切都会按预期工作

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();
}

您没有等待任务完成执行。这意味着您的应用程序将在任务引发异常之前结束

如果您只需添加一个
线程.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();
}

非常有趣。你能解释一下为什么去掉for循环也能解决这个问题吗?我被这种行为弄糊涂了。@MaYaN它不是for循环。。这是
线程。Sleep(1000)在它里面。当您删除它时,任务会在调用
GC.Collect
Perfect之前立即抛出,这是完全有意义的,我以前在GC.Collect之前有一个线程。Sleep(1000),这显然比循环完成所需的时间(5000)要短,这意味着到GC收集时,该任务实际上没有引发异常。这不是的重复,只是一个bug。@I3arnon:该问题的公认答案解释说,除非收集该任务,否则不会触发该事件。这很好地解释了为什么这个问题中的循环将异常延迟到足以通过
GC.Collect
调用。@Groo,我同意这是的重复,但我决定撤回投票。它立刻结束了这个问题,在这种情况下,一次投票可能会有太多的权力:)@Groo它没有。OP清楚地知道何时应该引发
unobservedtaskeexception
,并调用
GC.Collect
来引发它。她/他的问题是关于这个特定的代码块(其中有一个bug),在另一个问题中没有解决方案。我必须同意I3arnon,我熟悉观察到的/未观察到的异常是如何产生的,这段代码的问题是,在GC完成收集时,任务没有抛出任何异常。我编写此测试代码的动机是观察异常在GC未观察和收集时的行为。