如何在任务抛出exception而不等待终结器时使应用程序崩溃

我们在.Net 4(没有异步等待可用)应用程序中使用任务,有时它们用于启动“Fire and Forget”操作,如下所示:

private void Test() { Task task = Task.Factory.StartNew(() => { throw new ApplicationException("Test"); }); } 

我们希望此exception在不等待任务的情况下使应用程序崩溃(否则将其置于任务中是没有意义的,至少在我们的场景中)并且不等待终结器,因为我们想要在发生意外错误时关闭应用程序避免状态损坏(我们正在保存exception发生时的状态)。

我的猜测是,不知怎的,我们应该使用延续任务但是将延续代码放在另一个不会使应用程序崩溃的任务中,所以我在这里被阻止了。

任何帮助将非常感谢

编辑:如果切换到ThreadPool,结果是预期的结果。 以下代码崩溃了应用程序:

 ThreadPool.QueueUserWorkItem((c) => { throw new ApplicationException("Test"); }); 

我终于找到了如何做到这一点,即使它有点复杂:

 namespace ThreadExceptions { using System; using System.Threading; using System.Threading.Tasks; public static class TaskExtensions { public static Task ObserveExceptions(this Task task) { return task.ContinueWith((t) => { ThreadPool.QueueUserWorkItem((w) => { if (t.Exception != null) { foreach (Exception ex in t.Exception.InnerExceptions) { throw new TaskException(ex); } } }); }, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.PreferFairness); } } } 

这将使应用程序崩溃而无需等待任务。 那是我一直在寻找的。

使用FailFast尝试此解决方案

此方法在不运行任何活动的try / finally块或终结器的情况下终止进程。

 private void Test() { Task task = Task.Factory.StartNew(() => { Environment.FailFast("Test", new ApplicationException("Test")); }); } 

您可以编写自己的Task类,它包装您要使用的各种Task方法,并为其添加exception处理。

例如:

 public static class TaskWithExceptionHandling { public static Task StartNew(Action action) { var task = Task.Factory.StartNew(action); task.ContinueWith(exceptionHandler, TaskContinuationOptions.OnlyOnFaulted); return task; } private static void exceptionHandler(Task task) { // Handle unhandled aggregate task exception from 'task.Exception' here. Console.WriteLine("Exception: " + task.Exception.GetBaseException().Message); } } 

您可以像这样替换Task类:

 Task task = TaskWithExceptionHandling.StartNew(() => { throw new InvalidOperationException("Test exception"); }); Console.ReadLine();