2

我的 ASP.net MVC 项目中有一些代码可以异步发送消息。在某些情况下,该代码可能会失败并导致未处理的异常。我无法直接访问引发异常的代码或生成线程的代码,因此我无法在那里捕获和处理错误。我尝试在 Global.asax 中的 Application_Error 级别进行捕获,但该函数仅针对页面错误而不是后台错误引发。我还尝试通过实现 OnUnhandledException 来捕获 HTTP 模块,但我找不到捕获异常并阻止工作进程存在于其中的方法。

有没有办法防止这些错误变得如此致命?我知道它们是严重的错误,应该得到处理,但我希望它们不要为其他页面上的其他用户终止工作进程。

更多细节:

消息调度程序是 EventStore,我相信我在这种情况下遇到的问题是它试图反序列化从以前版本的 NServiceBus 实现 ICommand 的消息。更新到最新的测试版后,反序列化似乎失败了。不幸的是,我愚蠢地删除了导致错误的提交,因此我无法完全复制该问题。

到目前为止,我发现模拟错误的最佳方法是

   public virtual ActionResult Error()
    {
        Task.Factory.StartNew(blowup);
        return new EmptyResult();
    }
    private void blowup()
    {
        throw new Exception("snap");
    }

您会注意到 snap 异常被抛出并被正确处理而不会引起问题。但是,如果您等待,那么我们没有观察到 Task 的异常属性的事实最终会杀死整个应用程序。

针对 Cassini 进行了测试,但在 IIS 7.5 上看到了类似的行为。

4

2 回答 2

1

问题是任何未处理的异常都会导致进程中止。此问题与 ASP.NET 无关。

连接 unobservedtaskexception 事件 ( http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.unobservedtaskexception.aspx ) 以捕获所有异常(并向您发送电子邮件)。

我认为将这个事件加上 Application_Error 事件加上 Thread.UnhandledException 事件挂钩是最佳实践。

于 2012-02-23T21:49:43.800 回答
1

.NET 1.1 为所有未处理的异常提供了支持。它会悄悄地抓住他们,然后继续快乐地前进。

在 .NET 2.0 中,Microsoft 将其更改为您现在看到的行为:任何完全未处理的异常都会导致进程停止,但您可以通过 Application_Error 方法的“处理程序汤”,Thread.UnhandledException 事件来处理其中一些异步异常,在 .NET 4.0 中,TaskScheduler.UnobservedTaskException。

Microsoft 提供了一个配置值来恢复 .NET 1.1 行为,这在 Web 应用程序中非常关键,其中一个错误异常可能会回收整个进程,从而破坏进程中有价值的缓存项。

在该<runtime>部分:

<legacyUnhandledExceptionPolicy enabled="1"/>

Microsoft 文章托管线程中的异常更详细地解释了所有这些。

于 2012-02-25T07:59:23.623 回答