【问题标题】:IDisposable, using and GarbageColleciton [duplicate]IDisposable,使用和 GarbageColleciton [重复]
【发布时间】:2020-07-22 12:15:03
【问题描述】:

我陷入了 IDisposableGarbageCollector 工作方式的混乱之中。

假设您有一个IDisposable 对象,它实际上 没有它所持有的资源(但Dispose() 方法在调用时会做一些事情)。并且假设您在 using 块的头部声明它,但实际上并没有在块的过程中与对象交互。

我对@9​​87654329@ 的运作方式有什么保证?

using(new MyConceptuallyDisposableObject())
{
   DoSomeWork();
   await DoSomeAsyncWork();
}//PointX

注意:

  • MyConceptuallyDisposableObject 未声明终结器/析构器。
    • (假设开发者永远不会忘记using`.Dispose()`我的对象)
  • MyConceptuallyDisposableObject 不会在任何地方调用 GC.SuppressFinalise(this)

我是否保证我构建的object 会:

  1. PointX 之前不会有.Dispose() 调用它吗?
  2. .Dispose()PointX.Dispose()上调用它吗?
  3. 不会PointX987654338@PointXPointXPointX
  4. 之前的任何时间得到 GarbageCollected/Finalised?
  5. 不会在调用 .Dispose() 之前获得 GarbageCollected/Finalised?

假设我随后更改我的代码以使 MyConceptuallyDisposableObject 在其构造函数中调用 GC.SuppressFinalise(this)。 (请记住,没有任何 Destructor 或 Finaliser)

  1. 这会改变上述具体问题的任何答案吗?
  2. 那么大体上会发生什么变化吗?
  3. 这是否意味着GC 根本不会清理我的对象,最终会导致内存泄漏?

*语境:*

为那些不可避免地好奇的人发布,但不要回答基于建议其他方法来实现这一点或我不应该这样做。现在,我更多的是从抽象意义上理解上述概念的内涵,而不是讨论我最初的尝试是否明智。

我想写一个DisposableAction() 类,它接受2 个Actions。一个在你构建它时执行,一个在你Dispose()它时执行。

我以为我知道以上所有问题的答案(并且它们是“是”、“是”、“是”、“是”、“否”、“除非你是 难以置信性能敏感”和“否”。),但我一直在尝试诊断一个似乎与这些信念相矛盾的错误。

【问题讨论】:

  • 这感觉像是一个 XY 问题。显然有一个错误超出了您的期望。你能告诉我们那个错误的minimal reproducible example吗?
  • 对于 1 - 不,没有这样的保证,因为显然一些其他代码可以在对象上调用 Dispose(奇怪,当然,但可能)。
  • 您是否知道可以通过其他方式到达“点 X”,然后依次执行两行代码,例如当第一行引发异常时?
  • 3 可能比大多数人想象的要复杂一些。 cbrumme 的博客文章(镜像cnblogs.com/tanglaoya321/archive/2013/06/07/3125442.html)在这里很有帮助。例如In other words, ‘this’ can be collected even while you are executing an instance method on that object. 实际上,由于您没有终结器,因此很难想象这会给您带来问题。

标签: c# garbage-collection idisposable using-statement finalization


【解决方案1】:

IDisposable 和垃圾回收无关,除了对象实现了碰巧调用.Dispose()的终结器的一种情况。

除非您确定、100% 明确地知道对象具有调用 .Dispose() 的终结器,否则您必须明确调用 .Dispose()(或使用 using确保对象已被处置。

您的问题的答案:

  1. 是的。
  2. 是的。
  3. 是的。
  4. 是的。
  5. 没有。
  6. 没有。
  7. 没有。

【讨论】:

  • @mjwills 说了什么。 :) 我不是在问GC 是否会专门调用.Dispose() [我知道肯定不会]。我询问了框架调用的总调用集。
  • @mjwills - 抱歉,我完全没有看到房间里的 using 大象。我已经更新了我的答案。
  • @LasseV.Karlsen - 见我上面的注释。
猜你喜欢
  • 2011-12-20
  • 1970-01-01
  • 2014-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-20
  • 2017-01-21
  • 2018-10-30
相关资源
最近更新 更多