C# 我是否应该在共享进程生命周期的对象上调用dispose?

C# 我是否应该在共享进程生命周期的对象上调用dispose?,c#,dispose,idisposable,C#,Dispose,Idisposable,我知道,所有实现了IDisposable的对象都应该在不再需要时立即处理,以便释放其非托管资源所使用的内存 我的问题与我知道的对象有关,因为事实上,这些对象将一直存在,直到主机进程本身终止。如果我把它们处理掉,会有什么不同吗?进程死亡时内存是否有可能无法释放?GDI对象呢?当进程死亡时,即使没有处理GDI句柄,它们也会被释放吗 我完全理解以任何方式处置所有物体都是一种良好的做法。我这样问纯粹是出于好奇。这取决于所讨论的对象(资源) 当进程终止所有非托管内存时,将释放文件句柄和其他操作系统资源,即

我知道,所有实现了
IDisposable
的对象都应该在不再需要时立即处理,以便释放其非托管资源所使用的内存

我的问题与我知道的对象有关,因为事实上,这些对象将一直存在,直到主机进程本身终止。如果我把它们处理掉,会有什么不同吗?进程死亡时内存是否有可能无法释放?GDI对象呢?当进程死亡时,即使没有处理GDI句柄,它们也会被释放吗

我完全理解以任何方式处置所有物体都是一种良好的做法。我这样问纯粹是出于好奇。

这取决于所讨论的对象(资源)

当进程终止所有非托管内存时,将释放文件句柄和其他操作系统资源,即使关联的终结器无法运行

但我不太确定db句柄、命名互斥体等

因此,在您认为不调用Debug的安全之前,您必须了解资源类型及其与进程的关系。根据一般原则调用Dispose()要容易得多

但这是一个理论上的论点,大多数类将使用
SafeHandle:CriticalFinalizerObject
。所以我认为这从来不是一个真正的实际问题

否。根据设计,IDisposable允许程序提前释放非托管资源,早于终结器可以完成的时间。它在相当不可预测的时间运行,通常在执行垃圾收集之后运行。你无法预测这种情况何时发生

在程序退出时处理没有意义,终结器保证在AppDomain卸载和进程关闭之前运行


也就是说,代码中存在一些可识别的滥用,这些代码实际上希望您调用它。但这通常基于using语句,因此不太可能遇到这种情况。

默认情况下,每个具有终结器的对象都将运行其终结器。相反,您可以从代码进行控制:您的
Dispose
可以调用
GC.SuppressFinalize
来表示不再需要终结器。(编辑:事实上,我认为每个对象都有一个终结器,但默认情况下它什么也不做。)@hvd-理论上,GC可以跳过一个正常的终结器。@hvd-“我认为每个对象都有一个终结器“正确”,但默认情况下它什么也不做”。也对,很幸运。真正的终结器是昂贵的。大家都同意,这在C语言中被称为“好像”规则,但这一原则同样适用于其他语言和环境:如果程序无法判断终结器没有运行,因为终结器没有任何副作用,然后,终结器不必运行。当创建覆盖
Finalize
的对象时,会创建一种特殊的弱引用,并将其存储在覆盖
Finalize
的对象列表中,以及一些其他簿记信息。即使对象立即在自身上调用
GC.SuppressFinalize()
,也不会避免系统设置该引用所需的工作,也不会允许在收集对象本身之前发布簿记信息。不覆盖
Finalize
的对象永远不会放在列表上,通常不需要创建簿记信息。哇,人们因为我说不要处理垃圾而像一群狗骑在三条腿的猫身上一样对我大发雷霆。我发现这样做弊大于利。生命周期不应该由一个容器而不是硬代码来管理吗?@CrazyDart,谢谢,这是一个iteresting读物,尽管它主要处理的问题是“X类型的对象是否应该正常被处置”。我试图回答的更具体的问题是“X类型的对象(通常肯定应该被处置)是否应该被处置,即使它共享进程的生命周期?”@CrazyDart Dispose何时伤害了您?您给出的链接给出了一些不应调用Dispose的示例,但一般规则还是应该调用它,除非您有充分的理由不这样做。终结器不能保证在程序退出时运行。系统保证会做出一些努力来运行它们,但这并不意味着它们实际上会被执行。终结器非常讨厌,大多数对象都不应该有终结器。