Elmah抛出ObjectDisposedException

时间:2015-04-08 18:04:12

标签: c# multithreading elmah windows-identity

我使用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应用程序在等待响应时超时或挂起很长时间。

1 个答案:

答案 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);
        }
    }

警告适用:

  • 所有这一切都是记录到您的默认日志。它不会发送电子邮件或做 Elmah可以用HttpContext做的任何其他奇特的东西
  • 你不会得到死亡的全黄色屏幕 - 只是异常的ToString()表示,这不太有用。