C#既然我们已经有了终结器,为什么还要处理呢

C#既然我们已经有了终结器,为什么还要处理呢,c#,garbage-collection,finalizer,C#,Garbage Collection,Finalizer,我一直听到关于在finalizer和Dispose()方法中放置代码来处理非托管资源的建议。我不明白的是,因为在GC发生时会调用终结器,所以我们可以从技术上假设它总是被调用。既然如此,为什么还要费心处理一个物体呢?我错过什么了吗 既然如此,为什么还要费心处理一个物体呢 因为您无法控制终结器何时运行。很可能是GC运行过于频繁,而仅依赖终结器的程序可能因资源(文件句柄、数据库连接)不足而崩溃 最佳实践(一次性模式)使用终结器作为备份计划,经常认为终结器的执行是一个需要修复的错误 引用MSDN 虽然

我一直听到关于在finalizer和Dispose()方法中放置代码来处理非托管资源的建议。我不明白的是,因为在GC发生时会调用终结器,所以我们可以从技术上假设它总是被调用。既然如此,为什么还要费心处理一个物体呢?我错过什么了吗

既然如此,为什么还要费心处理一个物体呢

因为您无法控制终结器何时运行。很可能是GC运行过于频繁,而仅依赖终结器的程序可能因资源(文件句柄、数据库连接)不足而崩溃

最佳实践(一次性模式)使用终结器作为备份计划,经常认为终结器的执行是一个需要修复的错误

引用MSDN

虽然终结器在某些清理场景中是有效的,但它们已经 两个显著的缺点:

  • 当GC 检测对象是否符合收集条件。这种情况发生在 不需要资源后的一段未确定时间 不再开发人员可以或想要执行的时间之间的延迟 释放资源和实际释放资源的时间 由终结器发布的版本在以下程序中可能是不可接受的: 获取许多稀缺资源(容易耗尽的资源) 或者在资源使用成本较高的情况下(例如,大型 非托管内存缓冲区)

  • 当CLR需要调用终结器时,它必须推迟收集 直到下一轮垃圾回收( 终结器在集合之间运行)。这意味着对象的 内存(以及它引用的所有对象)将不会释放一段时间 更长的时间


或者如果终结器运行。有人链接了我正在思考的博客帖子:)是的,没错,这是一个极端的例子,但它说明了我们可以依靠终结器来实现资源发布逻辑的程度有多低。为什么这个问题被否决了?除非它是重复的,否则这是一个非常好的问题。同意@golergka,还有为什么接近得太宽?亨克设法用一句话概括了答案。有些人太容易被触发。@golergka请解释为什么这是一个“非常好的问题”?考虑到.NET的流行性,这个问题以前肯定会被问到(事实上一直如此,因此我以一个副本结束了投票)。它没有显示出任何研究努力或对该主题的理解。@CodeCaster我提到它可能是重复的,我只是没有检查它。但我不同意“不做研究”的说法。研究努力是相对的;我认为,由于您在方法中显示的要求很高,所以不会有任何新手问题,因为所有这些问题都可以通过阅读文档来解决。我不认为这是一个问题。