处理 UWP 应用中的调度程序异常

Kyb*_*ias 1 c# exception uwp

在我的 UWP 应用程序中,我需要从另一个线程更新 UI,我正在使用 CoreDispatcher 来执行此操作。我希望任何未处理的异常都会终止应用程序,就像 UI 线程中的异常一样,但情况似乎并非如此。下面的 RunAsync lambda 中引发的异常将被 UWP 静默忽略。此外,这些异常永远不会发送到任何应用程序 UnhandledException 处理程序(下面示例中的第二个异常是)。

到底是怎么回事?调度程序是否只是捕获所有异常并默默地忽略它们?

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();

        var dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;

        Task.Run( async () =>
        {
            await Task.Delay(2000);

            await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                throw new Exception("This exception will not terminate the app.");
            });
        });
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        throw new NotImplementedException("This will terminate the app");
    }
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*ake 5

从技术上讲,它们并不是无人处理的,因为任务中的异常被“捕获”并包装在 Task 对象中。如果任务中没有以某种方式消耗该异常(通过等待任务或使用 .ContinueWith),当任务被垃圾收集时,您可以监听TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;以获取该异常 - 如果您愿意,您可以从那里手动终止应用程序或重新抛出。

当然,请记住,根据您编写代码的方式,无法保证任务会被匆忙地垃圾收集,或者根本不会被垃圾收集 - 因此,如果您将任务的引用存储在任何地方,则很可能会默默地吞下如果你不小心的话,这样的例外。