获取任务的意外异常以在垃圾收集之前关闭应用程序

Mat*_*ith 5 c# exception-handling task-parallel-library

通常,对于我不希望抛出异常但代码(即编程错误)的代码,我希望我的应用程序崩溃(这样它不会破坏数据,向用户报告无效数据等).

使用时是否有获得(更接近)此行为的最佳做法Tasks?我们已经注册了一个处理程序TaskScheduler.UnobservedTaskException.问题是这可能比导致意外异常的时间晚得多.

问题: 如果有的话,我应该使用哪个选项:

  1. 我应该将我Task的操作包装在try/catch中并在catch中升级我不期望的异常吗?如果是这样,我该怎么做才能升级(即我想让它解雇AppDomain.UnhandledException事件并终止.

  2. 我应该OnlyOnFaulted在ui线程(这是Winforms应用程序)上附加continuation(),如果它不是预期的异常,它会重新抛出异常吗?

  3. 有更好或更标准的方法吗?

这是#1的样子:

var t1 = Task.Factory.StartNew(() =>
    {
        try
        {
            string path = null; // Programming error.  Should have been a valid string.  Will cause System.ArgumentNullException below
            using (FileStream fs = File.Create(path))
            {

            }
        }
        catch (System.IO.IOException) { throw; } // Expected possible exception
        catch (System.UnauthorizedAccessException) { throw; }
        catch
        {
            // Anything caught here is not an expected exception and should be escalated.
            // But how?
        }
    });
Run Code Online (Sandbox Code Playgroud)

这是#2的样子:

TaskScheduler uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
var t1 = Task.Factory.StartNew(() =>
    {
        string path = null; // Programming error.  Should have been a valid string.  Will cause System.ArgumentNullException below
        using (FileStream fs = File.Create(path))
        {

        }
    });

t1.ContinueWith(t =>
    {
        Exception ex = t.Exception;
        if (ex is IOException || ex is UnauthorizedAccessException) // Expected exceptions (do nothing)
            return;

        throw ex; // Not expected (escalate by rethrowing)

    }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, uiTaskScheduler);
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 2

对我来说,附加一个延续是一个很好的方法。如果您认为不会因为其他原因而阻塞 UI 线程太长时间,那么强制继续在 UI 线程上运行对我来说似乎是一个非常合理的选择。这样,您也可以执行您需要的任何 UI 任务,作为紧急关闭的一部分。