从异步任务中止当前进程

时间:2012-11-12 18:14:08

标签: c# .net task-parallel-library windows-error-reporting

我有一些复杂的函数在通过TPL生成的异步Task中运行,这可能偶尔会以意外的方式失败。发生此类故障时,这表示编程错误,可能导致程序状态损坏。因此,我不希望我的程序捕获异常,处理它并且" limp on",我希望我的进程崩溃并终止。

我还想让事情以Windows错误报告系统将其检测为崩溃的方式死掉,并执行所有有用的调试操作,如捕获minidump,将其发送给Microsoft等等。

我意识到这可能与你对错误条件下程序应该做什么的看法背道而驰,但问题不在于此。

我遇到的问题是,因为异常是从任务中引发的,所以它不会立即导致进程崩溃。一段时间后,垃圾收集器凭借其智慧决定收集未被观察到的#34;异常。

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

  • 来自实际错误的调用堆栈和线程转储是我要在崩溃转储中收集的内容
  • 过程"跛行"并且在一些不确定的时间后崩溃可能会造成进一步的破坏,因为它将会对可能腐败的程序状态起作用
  • 用户对实际导致崩溃的操作感到困惑

因此,简而言之,问题是:

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

提前致谢!

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

查看ThrowUnobservedTaskExceptionsapp.config设置):

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

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

     

在.NET Framework 4中   默认情况下,如果具有未观察到的异常的任务是垃圾   收集后,终结器抛出异常并终止   处理。该过程的终止由时间决定   垃圾收集和完成。

     

让开发人员更轻松   编写基于任务的异步代码,.NET Framework 4.5   更改未观察到的异常的此默认行为。未观测到   异常仍会导致引发UnobservedTaskException事件,   但默认情况下,该进程不会终止。相反,例外   无论是否发生事件,都会在引发事件后忽略   handler会观察异常。

     

在.NET Framework 4.5中,您可以使用   应用程序中的元素   配置文件,以启用.NET Framework 4抛出的行为   一个例外。

     

您还可以在其中一个中指定异常行为   以下方式:

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

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

  •