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
相关产品推荐
相关产品推荐

