异步中未处理的异常不会冒泡到Application_error

时间:2014-04-09 17:27:44

标签: asp.net asp.net-mvc exception async-await

我有一个异步操作,实际上来自ASP.net Identity,它在异步数据库查询中抛出异常。但是,这个异常似乎并不适用于我在Global.asax.cs中使用的一般application_error。其他例外正在被正确捕获。

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            var user = await UserManager.FindAsync(model.UserName.Trim(), model.Password.Trim());
            ...
        }
    }

在我的情况下,数据库已经更改而没有更新模型 - 但我真的想要一种机制,我可以全局应用于我所有的各种异步操作。

我确实看到另一篇文章建议在任务调度程序中挂钩到未观察到的异常,如下所示:

        TaskScheduler.UnobservedTaskException += (sender, e) =>
        {
            Console.WriteLine("Saving the day! This exception would have been unobserved: {0}",
                              e.Exception);
            e.SetObserved();
        };

然而,lambda中的断点永远不会被击中。我可以使用围绕异步的try / catch块来拦截异常,但这是高度明确的,并且无处不在。

我如何捕捉并至少记录这些例外情况?

2 个答案:

答案 0 :(得分:0)

使用或创建例外的日志记录表,当您的呼叫出现错误时,请记录异常。这样您还可以对日志表进行同步调用,查看异步调用是否有异常,检索它们,并将它们包含在通常的错误处理过程中。将它们包裹在ExceptionManager或类似的实体中,并在Global.asax.cs文件中出现错误时调用它,以确保报告所有错误。

答案 1 :(得分:0)

这种异常观察和处理行为背后有一个很好的理由,我已经描述过here

如果你想在async方法中记录异常,没有额外的包装代码,我只能想到"How to: Receive First-Chance Exception Notifications"