【发布时间】:2020-07-22 12:15:03
【问题描述】:
我陷入了 IDisposable 和 GarbageCollector 工作方式的混乱之中。
假设您有一个IDisposable 对象,它实际上 没有它所持有的资源(但Dispose() 方法在调用时会做一些事情)。并且假设您在 using 块的头部声明它,但实际上并没有在块的过程中与对象交互。
我对@987654329@ 的运作方式有什么保证?
即
using(new MyConceptuallyDisposableObject())
{
DoSomeWork();
await DoSomeAsyncWork();
}//PointX
注意:
- MyConceptuallyDisposableObject 未声明终结器/析构器。
- (假设开发者永远不会忘记
using`.Dispose()`我的对象)
- (假设开发者永远不会忘记
- MyConceptuallyDisposableObject 不会在任何地方调用
GC.SuppressFinalise(this)。
我是否保证我构建的object 会:
- 在
PointX之前不会有.Dispose()调用它吗? -
会在
.Dispose()PointX.Dispose()上调用它吗? -
不会在
PointX987654338@PointXPointXPointX 之前的任何时间得到 GarbageCollected/Finalised?
-
不会在调用
.Dispose()之前获得 GarbageCollected/Finalised?
假设我随后更改我的代码以使 MyConceptuallyDisposableObject 在其构造函数中调用 GC.SuppressFinalise(this)。 (请记住,没有任何 Destructor 或 Finaliser)
- 这会改变上述具体问题的任何答案吗?
- 那么大体上会发生什么变化吗?
- 这是否意味着
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