You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咨询:C#中Finalizer未被调用的原因及解决办法

为什么C#终结器未被调用?

你的代码里终结器没被调用,核心原因有两个:

  • 进程退出过快,GC未触发终结器:Main方法执行完毕后进程立刻终止,CLR为了快速结束程序,不会等待垃圾回收器完成终结器的执行流程。此时Test对象虽然符合回收条件,但GC还没来得及处理它。
  • CLR不保证终结器一定会执行:即使对象可被回收,CLR也没有承诺在任何场景下都会调用终结器,尤其是进程即将退出时,这种不确定性会被放大。

验证终结器的方法

如果想看到终结器执行,可以手动触发GC并等待终结器完成,修改代码如下:

using System;

class Program
{
    static void Main(string[] args)
    {
        Test test = new Test();
        // 解除对象引用,让它成为垃圾回收目标
        test = null;
        // 手动触发垃圾回收
        GC.Collect();
        // 等待所有pending的终结器执行完毕
        GC.WaitForPendingFinalizers();
    }
}

class Test
{
    public Test()
    {
        Console.WriteLine("Start");
    }   

    ~Test()
    {
        Console.WriteLine("End");
    }
}

运行这段代码就能看到"End"输出了。

更可靠的资源释放方式

依赖终结器释放资源并不推荐,因为其执行时机不可控。如果需要确保资源被及时释放,应该实现IDisposable接口,配合using语句显式管理资源:

using System;

class Test : IDisposable
{
    public Test()
    {
        Console.WriteLine("Start");
    }   

    ~Test()
    {
        Dispose(false);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // 释放托管资源(比如其他实现IDisposable的对象)
        }
        // 释放非托管资源
        Console.WriteLine("End");
    }
}

class Program
{
    static void Main(string[] args)
    {
        using(var test = new Test())
        {
            // 这里使用Test对象
        } // 离开using块时自动调用Dispose,输出"End"
    }
}

内容的提问来源于stack exchange,提问作者Emil Grigoryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 06:20:16