我的.net服务通过在Main()循环退出之前调用finally块中的resourceName.Dispose()来清理所有非托管资源。
我真的必须这样做吗?
我是否认为我不能泄漏任何资源,因为这个过程正在结束? Windows将关闭任何不再使用的句柄,对吧?
答案 0 :(得分:9)
在特定情况下,跳过这个可能是可以的。
首先要理解的是,虽然结束流程本身应足以清理大多数事情,但某些非托管资源可能会处于错误或未关闭的状态。例如,您可能拥有一个每个席位许可的应用程序,当应用程序关闭时,您需要更新某个位置的数据库记录以释放您的许可证。如果进程未正确终止,则不会发生任何更新,您最终可能会将人员锁定在您的软件之外。仅仅因为您的流程终止并不是不进行清理的借口。
然而,在具有IDisposable模式的.Net世界中,您可以获得更多保险。当进程退出时,所有剩余的终结器都将运行。 如果 Dispose()模式正确实现(并且它比它应该的更大“if”),终结器仍然在那里为其对象处理任何剩余的非托管资源...... / p>
然而,总是养成正确自己处理这些东西的习惯是一种好习惯。而FWIW,只是调用.Dispose()是不够的。您的.Dispose()调用必须作为finally块的一部分(包括使用using
语句获得的隐式finally块)。
答案 1 :(得分:8)
实现IDisposable
的对象可以封装的资源类型没有限制。当进程关闭时,操作系统将清除由IDisposable
对象封装的绝大多数资源,但某些程序可能会使用操作系统一无所知的资源。例如,需要底层数据库不支持的锁定模式的数据库应用程序可能会使用一个或多个表来跟踪“已检出”的内容以及由谁“检出”。使用这些表“检出”资源的类可以在其Dispose
方法中确保所有内容都被检入,但如果程序关闭而类没有机会清理表,那么资源保护那张桌子会悬空。由于操作系统不知道任何这些表的含义,它将无法清理它们。