未调用终结器

问题描述 投票:0回答:4

我有一个 C# 类,我想在处理我的类时正确关闭一些通信端口。但是,当我退出程序时,永远不会调用终结器。这是为什么?我是不是做错了什么?

我正在手动调用 dispose 来处理并关闭所有通信。这也没有被解雇。

这是我正在使用的终结器:

~Power()
{
    Dispose(false);
}
c# finalizer
4个回答
10
投票

终结器(这就是您在这里使用的)仅在终结阶段被调用,这将在 GC 期间发生。

如果正确实现 IDisposable,则永远不会调用它。我在 我的 IDisposable 系列中详细介绍了这一点。

话虽这么说,如果您的“通信端口”是通过托管类处理的,那么您根本不应该使用终结器。这增加了开销,对您没有任何帮助。只需(正确地)实现 IDisposable,并让端口类周围的托管包装器在需要时处理终结。


7
投票

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

using System;

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

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

程序终止时留下的任何对象的终结器都会在进程终止之前调用。唯一不会发生这种情况的方法是进程被粗暴地中止。例如,Environment.FailFast()。


1
投票

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


0
投票

在 2023 年,当终止

.NET
应用程序时,终结器(很可能)从不 被调用,如 MSDN 上所述:

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

当然,我们大多数人此时都会使用

.NET 5
或更晚的时间。因此,除非您打算坚持使用
.NET Framework
或运行一些非 Windows 兼容的
.NET
实现(例如某些云提供的
Linux
版本),否则不要依赖此行为。

相反,请使用

IDisposable
,正如一些人在这里建议的那样。

© www.soinside.com 2019 - 2024. All rights reserved.