我有一个MVC应用程序,我试图捕获ActionFilter中的所有传入请求。这是日志代码。我试图登录火灾并忘记模型。
我的问题是,如果我通过取出Task.Run Elmah发送电子邮件同步执行此代码。但是对于下面显示的代码,我可以看到错误记录到elmah.axd中的InMemory记录器但没有电子邮件。
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);
}
});
}
答案 0 :(得分:3)
在ELMAH谷歌小组获得Atif Aziz(Elmah Lead撰稿人)的回答
使用Task.Run时,HttpContext不会传输到将执行操作的线程池线程。当从您的操作中调用ErrorSignal.FromCurrentContext时,我的猜测是它可能因另一个异常而失败,因为没有当前上下文。这个例外就在于任务。如果您使用的是.NET 4,那么您很幸运,因为当GC启动并收集任务时,您最终会看到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))来记录错误。