不保证析构函数完成运行? [英] Aren't destructors guaranteed to finish running?

查看:250
本文介绍了不保证析构函数完成运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

析构函数的怪异的。我试图消除通过使用智能参考文献管理,确保垃圾收集器能够在正确的时间收集对象使用一次性模式的需要。在我的析构函数中的一个,我不得不等待另一个对象,我发现它没有一个事件。该应用程序干脆关机和析构函数在执行中间终止。
我期望析构函数总是被允许完成运行,但下面的测试表明,事实并非如此。

 使用系统;使用System.Diagnostics程序
;
使用的System.Threading;


命名空间DestructorTest
{
类节目
{
静态无效的主要(字串[] args)
{
新DestructorTest();
新LoopDestructorTest();
使用(新DisposableTest()){}
}
}

类DestructorTest
{
〜DestructorTest()
{
//这是不允许的完成。
Thread.sleep代码(10000);
}
}

类LoopDestructorTest
{
〜LoopDestructorTest()
{
INT CUR = 0;
的for(int i = 0; I< int.MaxValue ++ I)
{
CUR = I;
}
//这是不允许的完成。
的Debug.WriteLine(现);
}
}

类DisposableTest:IDisposable的
{
公共无效的Dispose()
{
//这当然被允许完成。
Thread.sleep代码(10000);
}
}
}



因此​​, AREN 'T析构函数保证完成运行?


解决方案

所以,不析构函数保证完成运行?




没有。从我记得,在进程终止时它给终结了几秒钟来执行,但随后突然终止进程。 ?你不会想要一个坏的终结,以防止一个过程从不断整理,你会



您应该把最后定稿为尽力而为清理 - 尤其是,它的的打算在整个系统突然关闭的情况下,比如蓝屏或停电发生



编辑:我已经发现,从乔·达菲一个博客文章的形式,一些伪文件




如果锁定在停止所有正在运行的线程的过程中成为孤儿,然后,关机代码路径将无法获取锁。如果这些收购与非超时(或长超时)获取完成,挂起将接踵而至。为了应对这种(以及任何其他种类挂起可能发生的),CLR的annoints看门狗线程以保持眼睛终结线程。虽然配置,默认情况下CLR会让终结了成为不耐烦前2秒跑完;如果超过此超时,终结器线程停止,继续关闭不消耗终结队列中的其余部分。



Destructors are weird. I was attempting to eliminate the need of using the disposable pattern by using 'smart' reference management, ensuring that the garbage collector could collect objects at the correct time. In one of my destructors I had to wait for an event from another object, which I noticed it didn't. The application simply shut down and the destructor was terminated in middle of execution. I'd expect a destructor is always allowed to finish running, but as the following test indicates that is not true.

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 );
        }
    }
}

So, aren't destructors guaranteed to finish running?

解决方案

So, aren't destructors guaranteed to finish running?

No. From what I remember, when the process terminates it gives finalizers a couple of seconds to execute, but then terminates the process abruptly. You wouldn't want a bad finalizer to prevent a process from ever finishing, would you?

You should regard finalization as a "best effort" clean-up - in particular, it's not going to happen in situations where the whole system is abruptly shut down, such as BSOD or power outage.

EDIT: I've found some pseudo-documentation in the form of a blog post from Joe Duffy:

If a lock was orphaned in the process of stopping all running threads, then, the shutdown code path will fail to acquire the lock. If these acquisitions are done with non-timeout (or long timeout) acquires, a hang will ensue. To cope with this (and any other sort of hang that might happen), the CLR annoints a watchdog thread to keep an eye on the finalizer thread. Although configurable, by default the CLR will let finalizers run for 2 seconds before becoming impatient; if this timeout is exceeded, the finalizer thread is stopped, and shutdown continues without draining the rest of the finalizer queue.

这篇关于不保证析构函数完成运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆