c# - 析构函数不能保证完成运行吗?

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

那么,析构函数不能保证完成运行吗?

最佳答案

So, aren't destructors guaranteed to finish running?

没有。据我所知,当进程终止时,它给终结器几秒钟的时间来执行,但随后突然终止了进程。您不会想要一个糟糕的终结器来阻止进程完成,对吗?

您应该将终结视为“尽力而为”的清理 - 特别是,它不会发生在整个系统突然关闭的情况下,例如 BSOD 或断电。

编辑:我发现了一些形式为 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.

关于c# - 析构函数不能保证完成运行吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9941688/

相关文章:

c# - Delegate.CreateDelegate() 和泛型 : Error binding to target method

c# - 使属性反序列化但不使用 json.net 序列化

c# - 在 excel 列之间插入列

c++ - 类构造函数、析构函数和运算符重载的实用函数

c++ - 析构问题

c++ - 调用了错误的析构函数

c# - AppDomain.Unload 抛出终结器?

C# 即使使用 "using System.Data.SqlClient;"也无法识别 SQLConnection

java - 对终结器的调用到底去哪里了

java - Java 中是否保证调用终结器?