5

Task我有一些通过 TPL以异步方式运行的复杂函数,有时可能会以意想不到的方式失败。当发生此类故障时,这表明可能导致程序状态损坏的编程错误。因此,我不希望我的程序捕获异常、处理它并“跛行”,我希望我的进程崩溃并终止。

我还希望这个东西以这样的方式死掉,即 Windows 错误报告系统将其检测为崩溃,并执行所有有用的调试操作,例如捕获小型转储、将其发送给 Microsoft 等。

我意识到这可能与您对程序在错误情况下应该做什么的看法背道而驰,但问题不在于那个。

我遇到的问题是,因为异常是从任务中引发的,所以它不会立即导致进程崩溃。一段时间后,当垃圾收集器根据自己的智慧决定收集“未观察到的”异常时,它会崩溃。

我希望该过程立即崩溃,因为...

  • 来自实际错误的调用堆栈和线程转储是我想在故障转储中收集的
  • 进程“一瘸一拐”并在稍后不确定的时间崩溃可能会导致进一步的损害,因为它将在可能损坏的程序状态下工作
  • 用户对实际导致崩溃发生的操作感到困惑

所以,简而言之,问题是:

如何使我的进程从Task使用 TPL 创建的 async 崩溃,以便 Windows 错误报告能够创建有用的小型转储?

提前致谢!

4

2 回答 2

4

你可以试试这个,或者类似的东西:

public static Task FailFastOnException(this Task task) 
{ 
    task.ContinueWith(c => Environment.FailFast(“Task faulted”, c.Exception), 
        TaskContinuationOptions.OnlyOnFaulted | 
        TaskContinuationOptions.ExecuteSynchronously | 
        TaskContinuationOptions.DetachedFromParent); 
    return task; 
}

接着:

var t = Task.Factory.StartNew(…).FailFastOnException();

我们刚刚将它用于“一劳永逸”的任务,如果它们由于某种原因失败,我们希望取消该过程。

摘自 Stephen Toub 撰写的博客文章:http: //blogs.msdn.com/b/pfxteam/archive/2009/05/31/9674669.aspx

于 2012-11-12T19:02:11.343 回答
0

看一下ThrowUnobservedTaskExceptionsapp.config设置):

<configuration>   
    <runtime>   
        <ThrowUnobservedTaskExceptions enabled="true"/>   
    </runtime>   
</configuration>

如果未观察到与 Task 关联的异常,则没有 Wait 操作,未附加父级,并且未读取 System.Threading.Tasks.Task.Exception 属性,则认为未观察到任务异常。

在 .NET Framework 4 中,默认情况下,如果对具有未观察到的异常的任务进行垃圾回收,则终结器会引发异常并终止进程。进程的终止由垃圾收集和终结的时间决定。

为了让开发人员更轻松地编写基于任务的异步代码,.NET Framework 4.5 更改了这种未观察异常的默认行为。未观察到的异常仍然会引发 UnobservedTaskException 事件,但默认情况下,进程不会终止。相反,无论事件处理程序是否观察到异常,都会在引发事件后忽略异常。

在 .NET Framework 4.5 中,您可以使用应用程序配置文件中的元素来启用 .NET Framework 4 引发异常的行为。

您还可以通过以下方式之一指定异常行为:

  • 通过设置环境变量 COMPlus_ThrowUnobservedTaskExceptions(设置 COMPlus_ThrowUnobservedTaskExceptions=1)。

  • 通过在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.NETFramework 项中设置注册表 DWORD 值 ThrowUnobservedTaskExceptions = 1。

于 2017-09-12T15:25:42.887 回答