考虑以下C#程序,我在codegolf上提交它作为创建循环而没有循环的答案:
class P{
static int x=0;
~P(){
System.Console.WriteLine(++x);
new P();
}
static void Main(){
new P();
}
}
这个程序在我的检查中看起来像一个无限循环,但似乎运行了几千次迭代,然后程序成功终止而没有错误(没有抛出错误)。是否违反了规范,P
的终结器最终未被调用?
显然这是愚蠢的代码,应该永远不会出现,但我很好奇程序是如何完成的。
原码高尔夫球员:: https://codegolf.stackexchange.com/questions/33196/loop-without-looping/33218#33218
答案 0 :(得分:110)
根据Richter在第二版CLR中通过C#(是的,我需要更新):
Page 478
对于(CLR正在关闭),每个 Finalize 方法大约需要两秒钟才能返回。如果 Finalize 方法在两秒内没有返回,则CLR会终止该进程 - 不再调用 Finalize 方法。此外,如果再次调用所有对象的 Finalize 方法需要40秒以上,CLR就会终止该过程。
此外,正如Servy所提到的,它有自己的主题。
答案 1 :(得分:23)
终结器不在主线程中运行。终结器有自己的运行代码的线程,它不是一个可以保持应用程序运行的前台线程。主线程立即有效地完成,此时终结器线程只是在进程被拆除之前运行多次。什么都没有让程序保持活力。
答案 2 :(得分:8)
垃圾收集器不是活动系统。它运行"有时"并且主要是按需(例如当操作系统提供的所有页面都已满)时。
大多数垃圾收集器在子线程中以类似广度的方式运行。在大多数情况下,物体回收可能需要数小时。
当您想要终止程序时,唯一的问题就出现了。然而,这不是一个真正的问题。当您使用kill
时,操作系统会礼貌地要求终止进程。但是,当该过程保持活动状态时,可以使用操作系统删除所有控件的kill -9
。
当我在交互式csharp
环境中运行您的代码时,我得到了:
csharp>
1
2
Unhandled Exception:
System.NotSupportedException: Stream does not support writing
at System.IO.FileStream.Write (System.Byte[] array, Int32 offset, Int32 count) [0x00000] in <filename unknown>:0
at System.IO.StreamWriter.FlushBytes () [0x00000] in <filename unknown>:0
at System.IO.StreamWriter.FlushCore () [0x00000] in <filename unknown>:0
at System.IO.StreamWriter.Write (System.Char[] buffer, Int32 index, Int32 count) [0x00000] in <filename unknown>:0
at System.IO.CStreamWriter.Write (System.Char[] buffer, Int32 index, Int32 count) [0x00000] in <filename unknown>:0
at System.IO.CStreamWriter.Write (System.Char[] val) [0x00000] in <filename unknown>:0
at System.IO.CStreamWriter.Write (System.String val) [0x00000] in <filename unknown>:0
at System.IO.TextWriter.Write (Int32 value) [0x00000] in <filename unknown>:0
at System.IO.TextWriter.WriteLine (Int32 value) [0x00000] in <filename unknown>:0
at System.IO.SynchronizedWriter.WriteLine (Int32 value) [0x00000] in <filename unknown>:0
at System.Console.WriteLine (Int32 value) [0x00000] in <filename unknown>:0
at P.Finalize () [0x00000] in <filename unknown>:0
因此,您的程序崩溃,因为stdout
被环境终止阻止。
删除Console.WriteLine
并终止程序时。程序终止后五秒钟(换句话说,垃圾收集器放弃并简单地释放所有内存而不考虑终结器)。