How to make an application crash when a task throws an exception without waiting for the finalizer to complete

We use Tasks in our .Net 4 application (not available for asynchronous waiting), and sometimes they are used to start Fire and Forget operations, such as the following:

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

We want this exception to crash the application without waiting for the task (since otherwise it makes no sense to have it in the task, at least in our scripts) and not waiting for the finalizer, since we want to terminate the application when an unexpected error occurs so that avoid state corruption (we maintain the state present when an exception occurs).

I suppose that somehow we have to work with the continuation task, but this puts the continuation code in another task that will not cause the application to crash, so I am blocked here.

Any help would be much appreciated

Edit: if you switch to ThreadPool, the result will be expected. The following code causes the application to crash:

 ThreadPool.QueueUserWorkItem((c) => { throw new ApplicationException("Test"); }); 
+4
source share
3 answers

I finally found how to do this, even if it's a little complicated:

 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); } } } 

This will crash the application without waiting for the task. This is what I was looking for.

+4
source

Try this solution using FailFast

This method terminates the process without any active try / finally blocks or finalizers .

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

You can write your own Task class, which wraps the various Task methods that you want to use, and add exception handling to it.

For instance:

 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); } } 

What would you replace for the Task class as follows:

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

All Articles