我在C#中有一个班级,我希望在处理班级时正确关闭一些通信端口。但是,退出程序时永远不会调用终结器。这是为什么?我做错了吗?
我正在手动调用dispose,它会通过并关闭所有通信。这也没有被解雇。
这是我正在使用的终结者:
~Power()
{
Dispose(false);
}
答案 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由垃圾收集器调用,垃圾收集不是一个可预测的过程,因此它不是很可靠。您需要找出其他方法来处置您的资源。