未调用终结器
我有一个 C# 类,我想在处理我的类时正确关闭一些通信端口。但是,当我退出程序时,永远不会调用终结器。这是为什么?我做错了什么吗?
我正在手动调用 dispose 来处理并关闭所有通信。这也没有被解雇。
这是我正在使用的终结器:
~Power()
{
Dispose(false);
}
I have a class in C# where I want to close out some communication ports properly when my class is being disposed. However, the finalizer is never being called when I exit the program. Why is that? Am I doing something wrong?
I am calling the dispose manually which goes through and closes all communications. This is not fired either.
Here is the finalizer I am using:
~Power()
{
Dispose(false);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
终结器(这就是您在这里使用的)仅在终结阶段调用,该阶段将在 GC 期间发生。
如果正确实现 IDisposable,则永远不会调用它。我在 我的 IDisposable 系列中详细介绍了这一点< /a>.
话虽这么说,如果您的“通信端口”是通过托管类处理的,那么您根本不应该使用终结器。这增加了开销,对您没有任何帮助。只需(正确地)实现 IDisposable,并让端口类周围的托管包装器处理终结(如果需要)。
The finalizer (which is what you're using here) is only called during the Finalization phase, which will happen during GC.
If you implement IDisposable correctly, this should never get called. I cover this in detail on my series on IDisposable.
That being said, if your "communication ports" are handled via managed classes, you shouldn't use a finalizer at all. This is adding overhead that does not help you whatsoever. Just implement IDisposable (properly), and let the managed wrappers around the port classes handle finalization if required.
如果一棵树倒在森林里,周围没有人听到,它会发出声音吗?确保它确实如此:
程序终止时留下的任何对象的终结器都会在进程终止之前调用。唯一不会发生这种情况的方法是进程被粗暴地中止。例如,Environment.FailFast()。
这个答案已经过时了,我需要编辑以指出 .NETCore(又名 .NET 5.0 及更高版本)的规则发生了变化。在旧框架中,终结器在 AppDomain 卸载时被调用。最常见的是在程序终止时。然而,AppDomains 在 .NETCore 中不再受支持,同时也无法保证调用终结器。
If a tree falls in the forest with no one around to hear, does it make a sound? Make sure it does:
The finalizers of any objects left at program termination are called just before the process terminates. The only way this won't happen is when the process is rudely aborted. Environment.FailFast() for example.
This answer is getting dated, I need to edit to point out that the rules changed for .NETCore (aka .NET 5.0 and up). In the legacy framework, finalizers were called when the AppDomain was getting unloaded. Most typically at program termination. AppDomains however became unsupported in .NETCore, along with it is the loss of guarantee that finalizers are getting called.
到 2023 年,当终止
.NET
应用程序时,(很可能)永远不会调用终结器,如 MSDN:当然,我们大多数人此时都使用 .NET 5 或更高版本。因此,除非您打算坚持使用 .NET Framework 或运行某些非 Windows 兼容的 .NET 实现(例如某些云提供的 .NET Framework),否则不要依赖此行为Linux 版本)。
相反,请使用
IDisposable
,正如一些人在这里建议的那样。In 2023, when terminating a
.NET
application, finalizers are (most likely) never called, as stated on MSDN:Sure most of us are using
.NET 5
or later at this point. Thus, don't rely on this behavior unless you plan to stick with.NET Framework
or running some non-Windows compatible.NET
implementation (e.g. some cloud providedLinux
version).Instead, use
IDisposable
as some have sugggested here.终结器由垃圾收集器调用,并且垃圾收集不是一个可预测的过程,因此它不是很可靠。您需要找出其他方法来处置您的资源。
Finalizer is called by garbage collector and the garbage collection is not a predictable process hence it is not very reliable. You need to figure out other means to dispose your resources.