我使用Windows身份验证和Elmah日志记录在IIS 7上运行了一个MVC应用程序。
通常在发生错误时,我们会调用类似“logger.LogError”的内容,它是以下内容的包装:
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(new Exception(message)));
我们设置了一个远程系统来运行定期ping Web应用程序的作业,以便将其唤醒并告诉它运行特定的作业。远程应用程序使用HttpClient :: GetAsync(...)连接到站点。
远程ping命中的页面,执行它需要在线程中运行但不等待的作业,因为我们希望ping立即响应。不幸的是,这还有打破Elmah伐木的额外缺点。
如果我们在作业执行期间发生任何类型的记录错误,当我们进入“LogError”方法时,Elmah会抛出一个“ObjectDisposedException”,并显示消息“Safe Handle已关闭”(可能是从尝试到访问当前用户身份)。我在调试时检查了监视窗口,抛出错误的部分是:
new Elmah.Error(new Exception(message))
如果我只调用“new Elmah.Error()”它工作正常,并且“new Exception(message)”也可以正常工作,但是当将异常作为参数传递给错误构造函数时,就会失败。此外,我无法在创建新的错误对象后分配异常,因为该属性是只读的。
我很确定这是因为当父窗口完成时,当前的Windows身份已经超出了父级线程的范围。有没有办法解决这个问题而不诉诸于等待执行工作?问题是作业可能需要很长时间才能运行,我们不希望远程ping应用程序在等待响应时超时或挂起很长时间。
答案 0 :(得分:4)
如果其他人碰到这个,这就是我最终做的事情:
在您通常打电话的情况下
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
改为调用此函数:
public static void LogError(Exception ex)
{
if (HttpContext.Current == null)
{
var errorlog = Elmah.ErrorLog.GetDefault(null);
var error = new Elmah.Error();
error.Message = ex.Message;
error.Detail = ex.ToString();
error.Time = DateTime.Now;
error.Type = ex.GetType() + "[NoContext]";
error.HostName = Environment.MachineName;
errorlog.Log(error);
} else {
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
}
警告适用: