如果应用程序崩溃,是否会调用析构函数?如果它是一个未处理的异常,我猜它确实如此,但更严重的错误,或用户杀死应用程序进程之类的东西呢?
还有一些可能是愚蠢的问题:
答案 0 :(得分:22)
我鼓励你自己尝试一下。例如:
using System;
class Program {
static void Main(string[] args) {
var t = new Test();
throw new Exception("kaboom");
}
}
class Test {
~Test() { Console.WriteLine("finalizer called"); }
}
在命令提示符下运行此命令,以便您可以看到最后一次喘气。首先将throw语句注释掉。
与Windows中任何未处理的异常一样,Windows提供的默认异常过滤器会调用WerFault.exe显示的Windows错误报告对话框。如果单击“关闭程序”,WerFault将使用TerminateProcess()来终止该程序。这是一个快速结束,没有机会运行终结器线程,就像程序正常退出时一样。
Windows然后负责清理弹片。它会自动关闭程序可能已打开的任何操作系统句柄,但没有机会在终结器中关闭。文件是一个棘手的问题,它们的缓冲区不会被刷新,你很容易在磁盘上找到部分写入的文件。
答案 1 :(得分:4)
我甚至不知道C#,但根据我对其他编程语言的经验,我猜:如果一个应用程序崩溃,那就意味着它有严重错误。不正确的内存处理等。在这种情况下,任何编程语言尝试执行析构函数/解除分配器/终结器/ ...都会很奇怪。事情可能会更加错误;)
更新:(忘了尝试回答其他问题),而不是C#特定的,但通常无法保证destructors / deallocators / finalizers / ...实际上被调用。这样做的原因是,当进程退出时,简单地“删除”用于进程的内存块比运行其析构函数等来清理内存更容易,更有效。
我不知道如何在不涉及太多技术细节的情况下回答您的上一个问题。有几种方法可以设计垃圾收集器并使其运行,最简单的方法是垃圾收集停止当前进程并在完成后继续进行,尽管也可能(但更难)使垃圾收集器同时运行他们正在收集的进程。
您可能希望阅读垃圾收集理论以更好地理解所有这些。实际上有一个关于这个主题的整个网站:www.memorymanagement.org。
答案 2 :(得分:3)
如果杀死一个应用程序,应用程序几乎100%立即丢失控件,并且它没有机会调用析构函数。