I have a C# Extension method that can be used with tasks to make sure any exceptions thrown are at the very minimum observed, so as to not crash the hosting process. In .NET4.5, the behavior has changed slightly so this won't happen, however the unobserved exception event is still triggered. My challenge here is writing a test to prove the extension method works. I am using NUnit Test Framework and ReSharper is the test runner.
I have tried:
var wasUnobservedException = false;
TaskScheduler.UnobservedTaskException += (s, args) => wasUnobservedException = true;
var res = TaskEx.Run(() =>
{
throw new NaiveTimeoutException();
return new DateTime?();
});
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.IsTrue(wasUnobservedException);
The test always fails on the Assert.IsTrue
. When I run this test manually, in something like LINQPad, I get the expected behavior of wasUnobservedException
coming back as true
.
I am guessing the test framework is catching the exception and observing it such that the TaskScheduler.UnobservedTaskException
is never being triggered.
I have tried modifying the code as follows:
var wasUnobservedException = false;
TaskScheduler.UnobservedTaskException += (s, args) => wasUnobservedException = true;
var res = TaskEx.Run(async () =>
{
await TaskEx.Delay(5000).WithTimeout(1000).Wait();
return new DateTime?();
});
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.IsTrue(wasUnobservedException);
The attempt I made in this code was to cause the task to get GC'd before the exception was thrown, so that the finalizer would see an uncaught, unobserved exception. However this resulted in the same failure described above.
Is there, in fact, some sort of exception handler hooked up by the Test Framework? If so, is there a way around it? Or am I just completely messing something up and there is a better/easier/cleaner way of doing this?