【发布时间】:2014-01-21 18:21:31
【问题描述】:
我有一个可用于任务的 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,这样终结器就会看到一个未捕获的、未观察到的异常。然而,这导致了上述相同的失败。
实际上,是否存在某种由测试框架连接的异常处理程序?如果是这样,有没有办法解决它?还是我只是完全把事情搞砸了,有更好/更容易/更清洁的方法吗?
【问题讨论】:
标签: c# exception nunit extension-methods unobserved-exception