Can I make an exception in Task.Run a program crash?

I'm not a big fan of quietly swallowed exceptions, but the following code does just that:

Task.Run(() => { var obj = DoSomethingCpuIntensive(); // returns null, due to a bug obj.DoMoreStuff(); Console.WriteLine("after"); // never get here; program continues running }); 

I read about the configuration value of ThrowUnobservedTaskExceptions , but that does not help, since I never do anything with the returned Task (editing: this actually helps, but only in Release versions).

Is there a way to make this unhandled exception crash the program? Do I Task.Run way I shouldn't?

+4
source share
3 answers

It seems that using Task.Run like this is really a bug. I think I should await , otherwise there will be such stupid things as above.

When it crashes with await , the debugger is pretty useless looking like this:

enter image description here

I take it all to keep in mind that I'm really doing the wrong thing with Task.Run here.

A simple fix uses the good old ThreadPool.QueueUserWorkItem instead:

enter image description here

This is much better! In any case, I do not need async / await in this code; I just used Task.Run because it printed less.

+1
source

I highly recommend you use Task.Run over ThreadPool.QueueUserWorkItem .

Take a step back first. What is the purpose of DoSomethingCpuIntensive ? If you are calculating some value, I suggest you return it, so instead of Task you have Task<T> . for example (assuming the DoMoreStuff not CPU intensive):

 async Task DoWorkAsync() { var obj = await Task.Run(() => DoSomethingCpuIntensive()); obj.DoMoreStuff(); } 

The idea I'm trying to understand is that your code should take care of the results of your background operations, even if the “result” is simply “success” or “exception”. Your code is cleaner. Otherwise, you have a semi-independent system that you can respond to by detecting changes in the state of your application. Much more randomly.

However, if you really want to have a semi-independent system, and you want it to break your process, if it fails, then ThrowUnobservedTaskExceptions is exactly what you want. I'm not sure why you think this will not help.

+1
source

You say you read about ThrowUnobservedTaskExceptions ; did you really try to run your program with ThrowUnobservedTaskExceptions set to true in your configuration?

The default behavior in .NET 4 is that unobservable Task exceptions reduce the whole process.

The default behavior in .NET 4.5 is that invisible Task exceptions will not slow down the process. Since you are running .NET 4.5, setting ThrowUnobservedTaskExceptions to true should do exactly what you need.

0
source

All Articles