Elmah不会在失火时发电子邮件 [英] Elmah Does not email in a fire and forget scenario

查看:67
本文介绍了Elmah不会在失火时发电子邮件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MVC应用,我试图在其中捕获ActionFilter中的所有传入请求。这是日志记录代码。我正在尝试登录并忘记模型。

I have a MVC app where I am trying to capture all the incoming requests in a ActionFilter. Here is the logging code. I am trying to log in a fire and forget model.

我的问题是,如果我通过取出Task来同步执行此代码。RunElmah确实会发送电子邮件。但是对于下面显示的代码,我可以看到该错误已记录到elmah.axd中的InMemory记录器中,但没有电子邮件。

My issue is if I execute this code synchronously by taking out the Task.Run Elmah does send out an email. But for the code shown below I can see the error getting logged to the InMemory logger in elmah.axd but no emails.

public void Log(HttpContextBase context)
        {
             Task.Run(() =>
            {
                try
                {
                    throw new NotImplementedException(); //simulating an error condition
                    using (var s = _documentStore.OpenSession())
                    {
                        s.Store(GetDataToLog(context));
                        s.SaveChanges();
                    }

                }
                catch (Exception ex)
                {
                    ErrorSignal.FromCurrentContext().Raise(ex);
                }
            });
        }


推荐答案

从Atif Aziz得到了这个答案(ELMAH首席贡献者)在ELMAH谷歌论坛上:

Got this answer from Atif Aziz (ELMAH Lead contributor) on the ELMAH google group:


使用 Task.Run HttpContext 不会传输到将在其上执行操作的线程池线程。从您的操作中调用 ErrorSignal.FromCurrentContext 时,我的猜测是它可能由于另一个异常而失败,因为当前没有上下文。该任务属于例外情况。如果您使用的是.NET 4,那么您会很幸运,因为当GC启动并收集Task时,您最终将看到ASP.NET应用程序崩溃(但可能在事后很多时候),并且其异常将未被观察到 。如果您使用的是.NET 4.5,则该策略已更改,该异常将完全丢失。无论哪种方式,您的观察都将是邮件无法正常工作。实际上,除非您使用 Elmah.ErrorLog.GetDefault(null).Log(new Error(ex))(不允许使用空上下文),否则日志记录也不起作用。但是该调用仅记录错误,但不发送任何邮件。 ELMAH的模块已连接到ASP.NET上下文。如果您通过派生到另一个线程来脱离该上下文,那么您将无法依赖ELMAH的模块。您只能可靠地使用 Elmah.ErrorLog.GetDefault(null).Log(new Error(ex))来记录错误。

When you use Task.Run, the HttpContext is not transferred to the thread pool thread on which your action will execute. When ErrorSignal.FromCurrentContext is called from within your action, my guess is that it's probably failing with another exception because there is no current context. That exception is lying with the Task. If you're on .NET 4, you're lucky because you'll see the ASP.NET app crash eventually (but possibly much after the fact) when the GC will kick in and collect the Task and its exception will go "unobserved". If you're on .NET 4.5, the policy has been changed and the exception will simply get lost. Either way, your observation will be that mailing is not working. In fact, logging won't work either unless you use Elmah.ErrorLog.GetDefault(null).Log(new Error(ex)), where a null context is allowed. But that call only logs the error but does not do any mailing. ELMAH's modules are connected to the ASP.NET context. If you detach from that context by forking to another thread, then you cannot rely on ELMAH's modules. You can only use Elmah.ErrorLog.GetDefault(null).Log(new Error(ex)) reliably to log an error.

这篇关于Elmah不会在失火时发电子邮件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆