Ste*_*ris 7 c# destructor finalizer
析构函数很奇怪.我试图通过使用"智能"参考管理来消除使用一次性模式的需要,确保垃圾收集器可以在正确的时间收集对象.在我的一个析构函数中,我不得不等待来自另一个对象的事件,我注意到它没有.应用程序只是关闭,析构函数在执行过程中被终止.我希望总是允许析构函数完成运行,但是下面的测试表明这不是真的.
using System;
using System.Diagnostics;
using System.Threading;
namespace DestructorTest
{
class Program
{
static void Main( string[] args )
{
new DestructorTest();
new LoopDestructorTest();
using ( new DisposableTest() ) { }
}
}
class DestructorTest
{
~DestructorTest()
{
// This isn't allowed to finish.
Thread.Sleep( 10000 );
}
}
class LoopDestructorTest
{
~LoopDestructorTest()
{
int cur = 0;
for ( int i = 0; i < int.MaxValue; ++i )
{
cur = i;
}
// This isn't allowed to finish.
Debug.WriteLine( cur );
}
}
class DisposableTest : IDisposable
{
public void Dispose()
{
// This of course, is allowed to finish.
Thread.Sleep( 10000 );
}
}
}
Run Code Online (Sandbox Code Playgroud)
那么,是不是保证完成运行的析构函数?
Jon*_*eet 16
那么,是不是保证完成运行的析构函数?
不.从我记忆中来看,当进程终止时,它会给终结器几秒钟的执行时间,然后突然终止进程.你不会想要一个糟糕的终结器来阻止一个进程完成,是吗?
您应该将最终确定视为"尽力而为"的清理 - 特别是,在整个系统突然关闭的情况下,例如BSOD或停电,情况不会发生.
编辑:我从Joe Duffy的博客文章中找到了一些伪文档:
如果在停止所有正在运行的线程的过程中锁被孤立,则关闭代码路径将无法获取锁.如果这些采集是在非超时(或长时间超时)获取的情况下完成的,则会发生挂起.为了解决这个问题(以及可能发生的任何其他类型的挂起),CLR会发出一个看门狗线程来监视终结器线程.虽然可配置,但默认情况下CLR会让终结器在变得不耐烦之前运行2秒; 如果超过此超时,则终止终结器线程,并且继续关闭而不会耗尽终结器队列的其余部分.