【发布时间】:2015-11-10 07:37:15
【问题描述】:
我有以下课程。现在有时 lock 语句会抛出 ArgumentNullException,在这种情况下,我可以在调试器中看到 disposelock 对象确实为空。
我可以看到 disposing 是错误的,我知道该方法是从 Finalizer 触发的。
但这怎么会发生呢?它被定义为只读,并在创建对象时获取其值。
PS:我知道这不是一个好的模式,但它是给定代码的一部分,我无法解释为什么它会变为 null
public abstract class DisposableMarshalByRefObject : MarshalByRefObject, IDisposable
{
private readonly object disposeLock = new object();
/// </summary>
~DisposableMarshalByRefObject()
{
Dispose(false);
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing) //disposing = false,=> finalizer
{
lock (disposeLock) //ArgumentNull Exception !
{
....
}
}
}
【问题讨论】:
-
请展示一个简短但完整的程序来说明问题。这在我看来似是而非。
-
有终结器吗?也许对象已经被释放,你需要抑制完成
-
关于垃圾收集(
~DisposableMarshalByRefObject())该收集的顺序(this- 首先,然后是 -disposeLock或disposeLock首先,然后是this) 未确定。 -
@BoasEnkler:
readonly,其实是一种语言特性。运行时不会阻止修改只读字段。例如,您可以使用反射来设置readonly字段值。 -
@JeppeStigNielsen 另一个可能触发锁的对象也可能符合垃圾回收条件,但引用了
DisposableMarshalByRefObject的实例。如果它的终结器触发了对不同线程上DisposableMarshalByRefObject上的方法的调用,则需要锁定。
标签: c# .net garbage-collection