gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 08:27:08 26 4
gpt4 key购买 nike

用于实现 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com