为什么应用程序在抛出异常时不会崩溃

Don*_*Box 1 c# multithreading task-parallel-library async-await

在WPF应用程序中,我添加了两个按钮,一个启动任务,另一个启动GC运行:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Task.Run(() =>
        {
            throw new Exception("Some Exception");
        });
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
Run Code Online (Sandbox Code Playgroud)

该任务只会引发异常.

在Release config中运行应用程序时,我按下第一个按钮,然后按下第二个按钮,我期待应用程序崩溃.无论按下按钮多少次,都不会发生这种情况.

我知道.NET 4.5中未观察到的任务吞咽异常的行为:https://blogs.msdn.microsoft.com/pfxteam/2011/09/28/task-exception-handling-in-net-4-5/

我很困惑,但为什么一旦GC运行,应用程序不会崩溃.根据我的理解,一旦收集任务,就应该抛出一个eception.

还要注意我知道这个问题没有回答我的问题 为什么当Task没有处理异常时我的进程没有终止?

标记为答案的注释建议使用,ContinueWith但这也不起作用,应用程序不会崩溃,吞下异常:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Task.Run(() =>
        {
            throw new Exception("Some Exception");
        }).ContinueWith(t =>
        {
            if (t.IsFaulted) { throw t.Exception.InnerException; }
        });
    }
Run Code Online (Sandbox Code Playgroud)

我已经知道等待任务使应用程序崩溃.

Raw*_*aew 5

这是因为你开火而忘记.异常将在单独的线程中发生.如果你想让它崩溃,你必须要await它或使它同步.

private void Button_Click(object sender, RoutedEventArgs e)
{
    await Task.Run(() =>
    {
        throw new Exception("Some Exception");
    });
}
Run Code Online (Sandbox Code Playgroud)


mm8*_*mm8 5

但我很困惑为什么一旦 GC 运行,应用程序就不会崩溃。根据我的理解,一旦收集了任务,就应该抛出接收。

如果您通过将以下元素添加到您的 中来使用旧行为(.NET Framework 4.5 之前的版本),您的理解是正确的App.config

<runtime>
    <ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
Run Code Online (Sandbox Code Playgroud)

如果您不这样做,则不会UnobservedTaskException导致进程崩溃。不过,仍然会引发异常,因此您可以在这两种情况下处理该事件。TaskScheduler.UnobservedTaskException


归档时间:

查看次数:

120 次

最近记录:

7 年,4 月 前