Boa*_*ler 22 .net c# garbage-collection
我有以下课程.现在有时锁定语句会抛出一个ArgumentNullException,在这种情况下,我可以在调试器中看到该disposelock对象实际上是null.
我可以看到处理是错误的,我知道该方法是从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 !
{
....
}
}
}
Run Code Online (Sandbox Code Playgroud)
在垃圾收集时,未定义该集合的顺序:
this收集disposeLock收集要么
disposeLock收集this收集因此,不要使用任何引用字段(结构类似int,bool等等是安全的)Dispose(false);
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
}
}
Run Code Online (Sandbox Code Playgroud)
除反思答案外,所有现有答案均为假.GC在收集对象时不会将引用设置为null.由于GC,对象访问不会发生虚假失败.最终确定的顺序是未定义的,但存在的所有对象引用仍然存在且有效.
我对发生的事情的猜测:构造函数在字段初始化之前被中止.那离开了这个领域null.终结者后来发现了那样.
可以通过抛出异常或通过调用Thread.Abort哪个是邪恶来中止构造函数.
在垃圾收集时,未定义该集合的顺序
收集的顺序是不可观察的(除非通过弱引用......).最终确定的顺序是可观察的,但不能与lock语句一起使用,因为对象在最终确定时不会失去同步的能力.
| 归档时间: |
|
| 查看次数: |
1459 次 |
| 最近记录: |