Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 析构函数-应用程序崩溃时会调用它吗_C#_.net_Destructor - Fatal编程技术网

C# 析构函数-应用程序崩溃时会调用它吗

C# 析构函数-应用程序崩溃时会调用它吗,c#,.net,destructor,C#,.net,Destructor,如果应用程序崩溃,是否调用析构函数?如果它是一个未处理的异常,我猜是的,但是对于更严重的错误,或者像用户杀死应用程序进程这样的事情呢 还有几个潜在的愚蠢问题: 当应用程序退出并且所有终结器都已执行时,应用程序中的所有对象会发生什么情况?这些对象是被垃圾收集,还是以某种方式被进程或appdomain“卸载” 垃圾收集器是每个应用程序的一部分(在同一进程中运行)还是独立的 我甚至不懂C,但根据我使用其他编程语言的经验,我猜:如果一个应用程序崩溃,那意味着它有严重的问题。内存处理不正确等。任何编程语

如果应用程序崩溃,是否调用析构函数?如果它是一个未处理的异常,我猜是的,但是对于更严重的错误,或者像用户杀死应用程序进程这样的事情呢

还有几个潜在的愚蠢问题:

  • 当应用程序退出并且所有终结器都已执行时,应用程序中的所有对象会发生什么情况?这些对象是被垃圾收集,还是以某种方式被进程或appdomain“卸载”
  • 垃圾收集器是每个应用程序的一部分(在同一进程中运行)还是独立的
我甚至不懂C,但根据我使用其他编程语言的经验,我猜:如果一个应用程序崩溃,那意味着它有严重的问题。内存处理不正确等。任何编程语言尝试执行析构函数/deallocators/finalizers/…都会很奇怪。。。在这种情况下。事情可能会变得更糟;)

更新:(忘了回答您的其他问题)同样,不是特定于C,但通常不能保证析构函数/DealLocator/finalizers/。。。实际上是接到电话。原因是,当进程退出时,简单地“zap”用于进程的内存块要比运行其析构函数等清理内存容易得多,效率也更高

我不知道如何在不涉及太多技术细节的情况下回答你的最后一个问题。垃圾收集器的设计和运行有几种方法,最简单的方法是垃圾收集停止当前进程并在完成后继续进行,尽管垃圾收集器也可能(但更难)与正在收集内存的进程同时运行


您可能需要阅读垃圾收集理论,以便更好地理解所有这些。实际上,整个网站都在讨论这个主题:。

如果杀死一个应用程序,该应用程序将几乎100%立即失去控制,并且没有机会调用析构函数

我鼓励你自己尝试一下。例如:

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负责清理弹片。它会自动关闭程序可能已打开但没有机会在终结器中关闭的任何操作系统句柄。文件是这里比较棘手的问题,它们的缓冲区不会被刷新,您很容易在磁盘上得到一个部分写入的文件。

什么样的崩溃?异常不是崩溃,而是可恢复的错误。Thx,很好的答案。但是有一件事似乎不正确-你说即使应用程序正常退出,一些析构函数仍然可能不会被调用。。。在我看来,这是不对的,因为垃圾收集器或任何其他人(除了对象本身)都无法知道应用程序的托管对象可能使用了哪种本机资源,所以它无法处理这一点。无论如何,我会尝试一下,正如nobugs所建议的那样,在我有时间的时候发布结果……我真的不能说是C,但Objective-C在这里提供了一个有趣的例子。您应该比较“dealloc”(当GC关闭时是析构函数)和“finalize”(当GC打开时)的文档。对于“dealloc”,文档非常明确地说,不保证会调用它,您不应该依赖它来关闭文件。对于“finalize”,文档更模糊,似乎建议您可以将“finalize”作为“备份”,以确保文件关闭等。,但是我找不到一句明确地说“finalize”一定会被调用的句子。这里有一个链接,指向Objective-C中“dealoc”和“finalize”的文档。顺便说一句:虽然只是尝试一个实验,看看这些在C中调用是否好,但你也应该看看文档。如果您的实验表明它被调用,但文档没有说有保证,那么这可能会在未来版本或其他平台上更改,因此您最好不要依赖它。Obj-C文件。链接:我对Objective-C中“finalize”的文档进行了更深入的研究,发现了这样一句话:“对象在收集对象时,在对象的生命周期内最多发生一次。”请注意,他们没有说“恰好一次”,而是说“最多一次”,这对我来说意味着可能是1次或0次。因此,至少在Objective-C中,不能保证“finalize”会被调用。我希望大多数其他语言(包括C#)也是如此,因为不保证操作系统或虚拟机可以在可能的情况下更快地清理内存。Thx,信息量很大。我一定会给这个和其他一些想法,看看发生了什么。