Question

I have some complex functions that run in an async Task spawned via the TPL, which could occasionally fail in unexpected ways. When such a failure occurs, this indicates a programming error which could have resulted in corrupted program state. Therefore, I don't want my program to catch the exception, handle it and "limp on", I want my process to crash and terminate.

I also want the thing to die in such a way that the Windows Error Reporting system detects it as a crash, and does all the useful debugging things like catching a minidump, sending it to Microsoft, etc.

I realise this may run counter to your opinions of what programs should do in error conditions, but the question is not about that.

The problem I have is, because the exception is raised from a task, it doesn't immediately cause the process to crash. It crashes some time later when the garbage collector, in its wisdom, decides to collect the "unobserved" exception.

I want the process to crash immediately, because...

  • The call stack and thread dump from the actual error is what I want to collect in the crash dump
  • The process "limping on" and crashing some indeterminate time later could cause further damage, as it will be working on a possibly corrupt program state
  • Users get confused about what operation actually caused the crash to occur

So, in short, the question is:

How can I cause my process to crash from an async Task, created with the TPL, such that Windows Error Reporting is able to create a useful minidump?

Thanks in advance!

Was it helpful?

Solution

You could try this, or something similar:

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

and then:

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

We've just used it a lot with "fire and forget" tasks that we want to take down the process if they for some reason fail.

Taken from a blog post written by Stephen Toub: http://blogs.msdn.com/b/pfxteam/archive/2009/05/31/9674669.aspx

OTHER TIPS

Take a look at ThrowUnobservedTaskExceptions (app.config setting):

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

If an exception that is associated with a Task has not been observed, there is no Wait operation, the parent is not attached, and the System.Threading.Tasks.Task.Exception property was not read the task exception is considered to be unobserved.

In the .NET Framework 4, by default, if a Task that has an unobserved exception is garbage collected, the finalizer throws an exception and terminates the process. The termination of the process is determined by the timing of garbage collection and finalization.

To make it easier for developers to write asynchronous code based on tasks, the .NET Framework 4.5 changes this default behavior for unobserved exceptions. Unobserved exceptions still cause the UnobservedTaskException event to be raised, but by default, the process does not terminate. Instead, the exception is ignored after the event is raised, regardless of whether an event handler observes the exception.

In the .NET Framework 4.5, you can use the element in an application configuration file to enable the .NET Framework 4 behavior of throwing an exception.

You can also specify the exception behavior in one of the following ways:

  • By setting the environment variable COMPlus_ThrowUnobservedTaskExceptions (set COMPlus_ThrowUnobservedTaskExceptions=1).

  • By setting the registry DWORD value ThrowUnobservedTaskExceptions = 1 in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.NETFramework key.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top