问题标签 [finalizer]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
nhibernate - 为什么调用 NHibernate AdoTransaction 的终结器?
我正在分析单元和集成测试,我发现很多时间都花在了 NHibernate.Transaction.AdoTransaction 的终结器上——这意味着它没有得到正确处理。
我没有直接在代码中使用 AdoTransaction,所以它可能被 NHibernate 中的其他对象使用。知道我忘记处理什么了吗?
这是我的文本夹具:
c# - IDisposable、Finalizers 和非托管资源的定义
我正在努力确保我的理解IDisposable
是正确的,并且有些事情我仍然不太确定。
IDisposable
似乎有两个目的。
- 提供按需“关闭”托管对象的约定。
- 提供一个约定以释放托管对象持有的“非托管资源”。
我的困惑来自于确定哪些场景有“非托管资源”在起作用。
假设您正在使用 Microsoft 提供的IDisposable
实现(托管)类(例如,与数据库或套接字相关的)。
- 你怎么知道它是
IDisposable
只为上面的1还是1&2实现的? - 您是否负责确保释放内部可能持有或不持有的非托管资源?您是否应该向您自己的调用 instanceOfMsSuppliedClass.Dispose() 的类添加终结器(这将是正确的机制吗?)?
c# - (.net) CriticalFinalizerObject - 它到底有什么作用?
我对这个类的理解是,当你想确定类的终结器(析构函数)被调用时,你应该使用它,但从我做的几个测试来看,这似乎不是真的。如果它不能确保调用 dispose 方法,还有其他方法吗?例如,如果我想确保运行某些代码来结束我的对象,即使我通过任务管理器或其他方式关闭了我的程序?
.net - 什么是终结器队列和 Control+ThreadMethodEntry?
我有一个似乎泄漏内存的 WindowsForms 应用程序,因此我使用 Redgate 的 ANTS Memory Profiler 来查看我怀疑的对象,发现它们仅由已在Finalizer Queue上的对象持有。太好了,究竟什么是终结器队列?你能指出我最好的定义吗?你能分享一些轶事建议吗?
此外,Finalizer Queue 上的所有根 GC 对象都是名为“caller”的System.Windows.Forms.Control+ThreadMethodEntry对象的实例。我看到它涉及多线程UI交互,但除此之外我知道的不多。原谅我明显的懒惰和承认的无知,但这些资源都埋在供应商的组件中。我正在与供应商讨论这些问题,但我需要一些指导来加快对话速度。你能指出我对 ThreadMethodEntry 最有用的定义吗?有什么轶事建议吗?
另外,我什至应该关注终结器队列中的这些对象吗?
更新:这篇红门文章很有帮助。
c# - 错误:不要覆盖 object.Finalize。相反,提供一个析构函数
在以下代码中出现上述错误。如何纠正它。谢谢。请寻找
在下面的代码中。
c# - 这是类层次结构的“传统”处置模式的合法替代方案吗?
我不喜欢样板代码:复制粘贴重用可能容易出错。即使您使用代码片段或智能模板,也不能保证其他开发人员做到了,这意味着不能保证他们做对了。而且,如果您必须查看代码,则必须理解和/或维护它。
我想从社区知道的是:我对类层次结构的IDispose实现是“传统”处置模式的合法替代方案吗?合法的,我的意思是正确的、性能相当好的、健壮的和可维护的。
我可以接受这种选择是完全错误的,但如果是,我想知道为什么。
此实现假定您可以完全控制类层次结构;如果你不这样做,你可能不得不求助于样板代码。对Add*()的调用通常在构造函数中进行。
这是一个“完整”的实现,因为我提供了对终结器的支持(知道大多数实现不需要终结器)、检查对象是否被释放等。真正的实现可能会移除终结器,例如,或创建一个包含终结器的DisposableObject的子类。基本上,我只为这个问题投入了我能想到的一切。
我可能错过了一些边缘情况和深奥的情况,所以我邀请任何人在这种方法中戳漏洞或通过更正来支持它。
其他选择可能是在DisposableObject中使用单个Queue<Disposer> 处理器而不是两个列表;在这种情况下,当调用处理程序时,它们会从列表中删除。我能想到其他一些细微的变化,但它们具有相同的一般结果:没有样板代码。
.net - 当对象超出 .Net 范围时可以运行代码吗?
一旦变量在.Net语言中失去作用域,有没有办法“自动”运行终结/析构函数代码?在我看来,由于垃圾收集器在不确定的时间运行,所以一旦变量失去作用域,析构函数代码就不会运行。我意识到我可以从 IDisposable 继承并在我的对象上显式调用 Dispose,但我希望可能有一个更不干涉的解决方案,类似于非.Net C++ 处理对象销毁的方式。
期望的行为(C#):
不太理想:
.net - DataGridViewRow 没有被垃圾收集
我有一个通过数据绑定对象定期填充的 DataGridView,并且行数可能会变大,例如在“日志记录周期”期间有数千行。
当一个新的“记录周期”开始时,网格被清除,因为底层数据源被清除并且该过程再次开始。
这一切都很好,但是因为之前的运行需要一些时间,所有之前的行都变成了第 2 代对象,并且只有在完整 GC 上进行垃圾收集。
但是,需要两次完整的 GC 才能清除它们,因为第一个将它们全部发送到终结器队列。这意味着它们占用内存的时间是原来的两倍。
使用反射器,我看到 DataGridViewRow 没有终结器方法,但它确实继承自 DataGridViewBand 对象,它确实 - 它通过它的公共 Dispose() 方法调用 GC.SuppressFinalize(this)。
所以我的问题是 - 为什么我的 DataGridViewRows 没有在第一次完整 GC 时被收集并进入等待另一个队列的终结器队列?
(我在这里的假设是,任何没有终结器的对象都不应该放在终结器队列中,并且任何有终结器但调用 GC.SuppressFinalize 的对象也不会放在队列中。我在这个假设中正确吗?)
谢谢。
wpf - 正确清理 WPF 用户控件
我对 WPF 比较陌生,它的一些东西对我来说很陌生。一方面,与 Windows 窗体不同,WPF 控件层次结构不支持 IDisposable。在 Windows 窗体中,如果用户控件使用任何托管资源,则通过重写每个控件实现的 Dispose 方法来清理资源非常容易。
在 WPF 中,事情并没有那么简单。我已经搜索了几个小时,并且遇到了两个基本主题:
第一个主题是 Microsoft 明确指出 WPF 不实现 IDisposable,因为 WPF 控件没有非托管资源。虽然这可能是真的,但他们似乎完全忽略了这样一个事实,即用户对其 WPF 类层次结构的扩展可能确实使用托管资源(直接或间接通过模型)。通过不实现 IDisposable,Microsoft 有效地删除了唯一有保证的机制,通过该机制可以清理自定义 WPF 控件或窗口使用的非托管资源。
其次,我发现了一些对 Dispatcher.ShutdownStarted 的引用。我曾尝试使用 ShutdownStarted 事件,但它似乎并没有为每个控件触发。我有一堆 WPF UserControl,我已经为 ShutdownStarted 实现了一个处理程序,并且它永远不会被调用。我不确定它是否仅适用于 Windows,或者 WPF App 类。但是它没有正确触发,每次应用程序关闭时我都会泄漏打开的 PerformanceCounter 对象。
有没有比 Dispatcher.ShutdownStarted 事件更好的方法来清理非托管资源?实现 IDisposable 是否有一些技巧可以调用 Dispose ?如果可能的话,我更愿意避免使用终结器。