我们有一个在WPF和Entity Framework之上运行的大型业务应用程序。问题是我们在过去两周内遇到了问题,无法确定其来源。
异常被DispatcherUnhandledException困住,我们从异常(通过电子邮件)获取的信息是这样的:
mscorlib: Value cannot be null.
at System.Threading.Monitor.ReliableEnter(Object obj, Boolean& lockTaken)
at System.Threading.Monitor.Enter(Object obj, Boolean& lockTaken)
at System.Data.EntityClient.EntityConnection.ChangeConnectionString(String newConnectionString)
at System.Data.EntityClient.EntityConnection.Dispose(Boolean disposing)
at System.ComponentModel.Component.Finalize()
例外情况是每天“随机”抛出4或5次,而且只有我们拥有的20多个用户中的一个。我们无法弄清楚问题!堆栈跟踪没有提供太多信息,我们无法重现问题。
我认为这是在一个线程上发生的,但我无法识别导致异常的线程,因为我们有很多BackgroundWorkers和异步的东西!
那么,我怎样才能获得有关异常的更多信息?
修改
没有任何InnerExceptions。
此外,异常是以分钟为单位,然后是小时,例如:11:41,11:46,11:51然后它运行正常,直到18:03,18:07,18:11然后没有抛出异常。此分钟间隔发生的时刻也是随机的,与服务器或网络上的任何负载无关。
答案 0 :(得分:3)
看起来这可能是垃圾收集线程的一部分。堆栈底部的Finalize调用是提示,然后可能调用EntityConnection.Dispose(false);
问题的本质是不确定的。在您的环境中,某些事情可能已经发生了变化。
在终结器中,访问其他托管对象真的不安全。看起来ChangeConnectionString可能试图将托管对象用作锁,有时当它在GC线程中时,该对象已被清除。这样做可能是EntityConnection中的一个错误。
您应该能够通过调用组件上的Dispose来避免这种情况,而不是让Finalizer运行(将它们包含在使用块中是确保这一点的好方法)。但是,使用callstack,很难说出引起问题的Component的性质。
如果要获取本地repro,请尝试使用覆盖Finalize的类(例如~MyComponent())继承正在访问EntityConnections的Component对象,并在其中抛出异常。这样,如果GC清理那些对象,你就会崩溃。
答案 1 :(得分:1)
" ReliableEnter值不能为空"错误意味着您正在尝试锁定设置为null的对象。
找到将对象设置为null的位置。
答案 2 :(得分:1)
我刚发生这种情况;就我而言,我过早处置SemaphoreSlim
。
我的代码类似于
using (var semaphore = new SemaphoreSlim(0, 1))
{
//... start task that will call semaphore.Release()
return func(); // this in turn calls semaphore.WaitAsync(timeout);
}
由于我没有await
-Task
返回的func
的信号,信号量过早Dispose
d,我得到的是“ ReliableEnter值不能为空“错误。