未调用终结器

发布于 2024-10-20 19:09:19 字数 196 浏览 1 评论 0原文

我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无法回应 2024-10-27 19:09:19

终结器(这就是您在这里使用的)仅在终结阶段调用,该阶段将在 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.

把回忆走一遍 2024-10-27 19:09:19

如果一棵树倒在森林里,周围没有人听到,它会发出声音吗?确保它确实如此:

using System;

class Program {
    static void Main(string[] args) {
        new Test();
    }
}

class Test {
    ~Test() { Console.Beep(); }
}

程序终止时留下的任何对象的终结器都会在进程终止之前调用。唯一不会发生这种情况的方法是进程被粗暴地中止。例如,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:

using System;

class Program {
    static void Main(string[] args) {
        new Test();
    }
}

class Test {
    ~Test() { Console.Beep(); }
}

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.

嘴硬脾气大 2024-10-27 19:09:19

到 2023 年,当终止 .NET 应用程序时,(很可能)永远不会调用终结器,如 MSDN

.NET 5(包括.NET Core)或更高版本:没有输出,
因为 .NET 的这个实现在以下情况下不会调用终结器:
应用程序终止。

当然,我们大多数人此时都使用 .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:

.NET 5 (including .NET Core) or a later version: There's no output,
because this implementation of .NET doesn't call finalizers when the
application terminates.

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 provided Linux version).

Instead, use IDisposable as some have sugggested here.

季末如歌 2024-10-27 19:09:19

终结器由垃圾收集器调用,并且垃圾收集不是一个可预测的过程,因此它不是很可靠。您需要找出其他方法来处置您的资源。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文