考虑以下 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
根据 CLR 第二版中的 Richter 通过 C# (是的,我需要更新):
第 478 页
对于(CLR 正在关闭)每个 Finalize 方法大约有两秒钟的返回时间。如果 Finalize 方法没有在两秒内返回,CLR 只会终止进程——不再调用 Finalize 方法。此外,如果调用所有对象的 Finalize 方法需要超过 40 秒,CLR 会再次终止该进程。
此外,正如 Servy 所提到的,它有自己的线程。
终结器不在主线程中运行。终结器有自己的线程来运行代码,它不是一个让应用程序保持运行的前台线程。主线程立即有效地完成,此时终结器线程只是在进程被拆除之前运行尽可能多的次数。没有什么能让程序保持活力。
垃圾收集器不是一个活动系统。它“有时”运行并且主要是按需运行(例如,当操作系统提供的所有页面都已满时)。
大多数垃圾收集器在子线程中以类似广度优先的方式运行。在大多数情况下,回收对象可能需要数小时。
唯一的问题发生在您想要终止程序时。然而,这并不是一个真正的问题。当您使用 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
并终止程序时。五秒钟后程序终止(换句话说,垃圾收集器放弃并简单地释放所有内存而不考虑终结器)。
P
实例的终结器只是超时了。
不定期副业成功案例分享