c# - MSDN Dispose() 示例错误? (何时将托管引用设置为空)

标签 c#

用于实现 Dispose() 方法的 MSDN's example pattern 描述了将对已处置托管资源的引用设置为 null (_resource = null),但在 if (disposing) 之外执行此操作> 阻止:

protected virtual void Dispose(bool disposing)
{
    // If you need thread safety, use a lock around these 
    // operations, as well as in your methods that use the resource.
    if (!_disposed)
    {
        if (disposing) {
            if (_resource != null)
                _resource.Dispose();
                Console.WriteLine("Object disposed.");
        }

        // Indicate that the instance has been disposed.
        _resource = null;
        _disposed = true;   
    }
}

_resource = null 不应该放在这个代码块中吗?如果调用 Dispose(false),则 _resource 将为 null 且随后无法处理! ??

当然,Dispose(false) 仅在终结期间由运行时调用(实际上)。但是如果_resource之前没有被disposed,那么在这个对象(包括_resource成员字段)即将成为垃圾的时候,为什么需要在此时将它设置为null收集到?


[原问题结束]

跟进:

经过大量阅读,似乎没有必要将引用设置为 null,但如果您有理由相信包含类(被处置的类)可能不会被垃圾收集,那么对于“重”成员对象来说可能是个好主意很快。

知道对象处置并不能保证对象已被消费代码“释放”。已处置的对象可能出于各种目的而被保留(在集合中或以其他方式),或者只是为了错误。我可以想象一个应用程序使用集合中的对象然后处理它们,但将它们保留在集合中以供以后执行删除和记录最终状态的过程(或类似的东西......谁知道......)

结论:

  1. 将对“重”成员对象的引用设置为 null 释放它们 用于垃圾回收,即使已处置的对象未被释放。
  2. 清除所有对象的引用是多余的。
  3. 因此,_resource = null 语句(原始问题)的放置并不重要,原因有二:(A) 完全使用它只是阅读上述内容后需要考虑的事情; (B) 在 MSDN 示例中,它针对 Dispose(true)Dispose(false) 执行,但后者仅在对象完成并即将执行时发生无论如何都要收集垃圾!

因此,我的偏好是将 _resource = null 放在最内部的 if block 中:

if (disposing) {
    if (_resource != null) {
        _resource.Dispose();
        _resource = null;
    }
}

这将所有 _resource 代码放在一起。进一步的想法,有人吗?

更多阅读:

最佳答案

将其设置为 null 会删除指向堆中位置的引用或指针。这让 GC 可以通过并删除任何没有引用它的东西,而不必做很多猜测。 _resource 将是一些需要清理其引用的内部使用对象,因此假设您在关闭内部有一个套接字,您将关闭/处置该套接字或任何其他持久资源。一旦它被处置,你将它设置为 null 并删除所有引用(应该删除所有引用)以便 GC 可以完成它的工作。我回答的第二部分是一个例子,所以它重复了一些事情,但我希望你能理解。

将它设置为 null 两次没什么大不了的,因为没有任何效果。在清理任何资源时 Disposing 应该是正确的,并且只有在(如您所说)即将被垃圾收集时它才是错误的。

关于c# - MSDN Dispose() 示例错误? (何时将托管引用设置为空),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6757048/

相关文章:

c# - 这是 Cast<T> 在 Controls 集合上的正常行为吗?

c# - 包含从 Request.Form 中挑选的数据的单元测试方法。新手问题

c# - 如何向子字符串添加 utc 偏移量 c#

c# - 二维数组错误的锯齿状数组

c# - 我有一个长时间运行的进程,我在服务总线队列中调用它。我希望它持续超过 5 分钟

c# - TypeScript 中的命名空间关键字

c# - 我怎样才能让 Sprite 在单人游戏中从一个位置到鼠标点击进行可见移动?

c# - 如何添加取消订阅链接,如下图所示

c# - 使用 Entity Framework 进行分组查询

c# - 如果嵌套语句的执行取决于第一个语句的结果,我该如何嵌套异步语句?