我有一个 C# 扩展方法,可以与任务一起使用,以确保所引发的任何异常都被观察到最低限度,以免使托管进程崩溃。在 .NET4.5 中,行为略有改变,因此不会发生这种情况,但仍会触发未观察到的异常事件。我在这里的挑战是编写一个测试来证明扩展方法有效。我正在使用 NUnit 测试框架,而 ReSharper 是测试运行器。
我努力了:
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);
测试总是在Assert.IsTrue
. 当我在 LINQPad 之类的东西中手动运行这个测试时,我得到了wasUnobservedException
以true
.
我猜测试框架正在捕获异常并观察它,以便TaskScheduler.UnobservedTaskException
永远不会触发。
我尝试修改代码如下:
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);
我在这段代码中所做的尝试是让任务在抛出异常之前获得 GC,这样终结器就会看到一个未捕获的、未观察到的异常。然而,这导致了上述相同的失败。
事实上,测试框架是否连接了某种异常处理程序?如果是这样,有没有办法解决它?还是我只是完全搞砸了一些事情,并且有更好/更容易/更清洁的方法来做到这一点?