我有以下类(class)。现在有时 lock 语句会抛出 ArgumentNullException
,在这种情况下,我可以在调试器中看到 disposelock
对象确实为 null。
正如我所看到的,disposing 是 false,我知道该方法是从 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 !
{
....
}
}
}
最佳答案
在垃圾收集上,该收集的顺序未定义:
- 首先收集
this
- 接下来收集
disposeLock
或者
- 先收集
disposeLock
- 接下来
this
集
所以不要使用任何reference字段(structs像int
, bool
等是安全的) 处置(假);
protected virtual void Dispose(bool disposing) {
if (disposing) {
// Explicit disposing: it's safe to use disposeLock
lock (disposeLock) {
...
}
}
else {
// Garbage collection: there's no guarantee that disposeLock has not been collected
}
}
关于c# - 从终结器处理时,只读字段变为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33624936/