Search code examples
c#.nettask-parallel-librarywindows-error-reporting

Abort current process from async task


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!


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