c# - 从终结器处理时,只读字段变为空

标签 c# .net garbage-collection

我有以下类(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 !
       {
           ....
       }
   }
}           

最佳答案

垃圾收集上,该收集的顺序未定义:

  1. 首先收集this
  2. 接下来收集disposeLock

或者

  1. 先收集disposeLock
  2. 接下来this

所以不要使用任何reference字段(structsint, 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/

相关文章:

c# - 如何确定 Exchange 邮件项目是否为自动回复邮件?

java - JVM内存管理和垃圾收集书?

java - jmap中显示的 "From Space"和 "To Space"是什么意思?

c# - Rhino 模拟/存储库测试 - NUnit 测试套件失败,但单个模拟单元测试通过?

c# - 如何显示哪个子正则表达式匹配失败?

.net - Sharepoint 2010将使用哪个版本的.net框架?

c# - 完成队列卡住

c# - 如何使用 C# 在 asp.net 中创建一个新文件夹?

c# - Linq to Objects 链接 where 子句 VS && 性能影响是微不足道的吗?

c# - 我们可以使用 C# 在 FTP 服务器中解压缩文件吗