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

C#中Disposable模式的Finalizer不保证被GC调用,为何仍需实现?

为什么Disposable模式中仍需实现终结器?

首先要明确:终结器不是“完全不保证被调用”,而是不保证在某个特定时间点被调用,且仅在进程异常终止的极端场景下会失效,但它仍是Disposable模式里不可或缺的兜底机制,核心原因有三点:

  • 兜底开发者的疏忽:显式调用Dispose是释放资源的最佳实践,但实际开发中难免出现遗漏——比如忘记用using块、代码抛出异常跳过了Dispose调用。这时候当GC回收对象时,终结器会触发,尝试释放非托管资源,避免资源长期泄漏。
  • 非托管资源的特殊性:非托管资源(如文件句柄、原生内存、网络连接)不受CLR管理,CLR无法自动回收它们。如果没有终结器,一旦开发者忘记显式释放,这些资源会一直被占用,直到进程结束,可能导致系统资源耗尽。
  • 大多数场景下会正常触发:只有在进程突然终止(比如崩溃、被强制杀死)或程序瞬间退出时,GC才没机会执行终结器。对于长时间运行的程序(如服务、桌面应用),GC会定期执行回收,终结器大概率会被调用,完成资源清理。

关于你的示例的说明

你的代码里终结器没被触发,是因为Main方法执行完后程序直接退出,进程终止时CLR不会等待终结器执行。如果修改代码让GC有机会运行:

class Program
{
    static void Main()
    {
        var myFileWriter = new FileWriter();
        // 解除引用,让对象成为垃圾
        myFileWriter = null;
        // 强制GC回收并等待终结器执行
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}

这时候就能看到文件被删除,终结器正常执行了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:48:13