没有调用终结器

时间:2011-03-05 00:51:17

标签: c# finalizer

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

我正在手动调用dispose,它会通过并关闭所有通信。这也没有被解雇。

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

~Power()
{
    Dispose(false);
}

4 个答案:

答案 0 :(得分:8)

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

如果正确实现IDisposable,则永远不应该调用它。我在my series on IDisposable上详细介绍了这一点。

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

答案 1 :(得分:5)

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

using System;

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

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

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

答案 2 :(得分:4)

不保证在任何特定时间调用C#终结器。他们不应该被误认为是C ++析构函数。

如果您想保证可预测的处理,请实现IDispose并在using块中实例化您的类:

using (Power power = new Power())
{
    //  blah blah
}

如果使用块不实用,请实现IDispose - 您必须编写一个Dispose方法来处理您需要释放的任何资源;有关所有具体要求,请参阅MSDN在线 - 并在适当的时间明确调用Dispose()。如果你是多线程的,可能需要一些同步代码来确保它不会太快发生。

答案 3 :(得分:0)

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