我有一个 C# 类,我想在处理我的类时正确关闭一些通信端口。但是,当我退出程序时,永远不会调用终结器。这是为什么?我是不是做错了什么?
我正在手动调用 dispose 来处理并关闭所有通信。这也没有被解雇。
这是我正在使用的终结器:
~Power()
{
Dispose(false);
}
终结器(这就是您在这里使用的)仅在终结阶段被调用,这将在 GC 期间发生。
如果正确实现 IDisposable,则永远不会调用它。我在 我的 IDisposable 系列中详细介绍了这一点。
话虽这么说,如果您的“通信端口”是通过托管类处理的,那么您根本不应该使用终结器。这增加了开销,对您没有任何帮助。只需(正确地)实现 IDisposable,并让端口类周围的托管包装器在需要时处理终结。
如果一棵树倒在森林里,周围没有人听到,它会发出声音吗?确保它确实如此:
using System;
class Program {
static void Main(string[] args) {
new Test();
}
}
class Test {
~Test() { Console.Beep(); }
}
程序终止时留下的任何对象的终结器都会在进程终止之前调用。唯一不会发生这种情况的方法是进程被粗暴地中止。例如,Environment.FailFast()。
Finalizer 由垃圾收集器调用,垃圾收集不是一个可预测的过程,因此不太可靠。您需要找出其他方法来处置您的资源。
在 2023 年,当终止
.NET
应用程序时,终结器(很可能)从不 被调用,如 MSDN 上所述:
.NET 5(包括.NET Core)或更高版本:没有输出, 因为 .NET 的这个实现在以下情况下不会调用终结器: 应用程序终止。
当然,我们大多数人此时都会使用
.NET 5
或更晚的时间。因此,除非您打算坚持使用 .NET Framework
或运行一些非 Windows 兼容的 .NET
实现(例如某些云提供的 Linux
版本),否则不要依赖此行为。
相反,请使用
IDisposable
,正如一些人在这里建议的那样。