为什么在main()退出之前调用Dispose()?

s d*_*s d 11 .net c# dispose handle resource-leak

我的.net服务通过在Main()循环退出之前调用finally块中的resourceName.Dispose()来清除所有非托管资源.

我真的必须这样做吗?

我是否认为我不能泄漏任何资源,因为这个过程正在结束?Windows将关闭任何不再使用的句柄,对吧?

Joe*_*orn 9

在特定情况下,跳过这个可能是可以的.

首先要理解的是,虽然结束进程本身就足以清除大多数事情,但是某些非托管资源可能会处于错误或未关闭的状态.例如,您可能拥有一个每个席位许可的应用程序,当应用程序关闭时,您需要更新某个位置的数据库记录以释放您的许可证.如果进程未正确终止,则不会发生任何更新,您最终可能会将人员锁定在您的软件之外.仅仅因为您的流程终止并不是不进行清理的借口.

但是,在具有IDisposable模式的.Net世界中,您可以获得更多保险.当进程退出时,所有剩余的终结器都将运行.如果 Dispose()模式正确实现(并且它比它应该的更大"if"),终结器仍然在那里处理其对象的任何剩余的非托管资源......

但是,总是养成正确处理这些东西的习惯是一种好习惯.而FWIW,只是调用.Dispose()是不够的.您的.Dispose()调用必须作为finally块的一部分包含在内(包括使用using语句获得的隐式finally块).

  • 虽然这个具体案例可能没问题,但鼓励这是一个坏习惯.你永远不知道该代码何时可能受到R&D(Rip-off和Deploy)的影响而进入另一个项目,然后就会发生不好的事情.每次都做这一点,你永远不必担心. (2认同)

sup*_*cat 9

对象实现可以封装的资源类型没有限制IDisposable.IDisposable当进程关闭时,操作系统将清除由对象封装的绝大多数资源,但某些程序可能会使用操作系统一无所知的资源.例如,需要底层数据库不支持的锁定模式的数据库应用程序可能会使用一个或多个表来跟踪"已检出"的内容以及由谁"检出".使用这样的表"检出"资源的类可以确保在其中Dispose重新检入所有内容的方法,但如果程序在没有机会清理表的情况下关闭,则该表保护的资源将保持悬空状态.由于操作系统不知道任何这些表的含义,它将无法清理它们.

  • 我认为这个答案最有意义:操作系统无法释放它不知道的资源。 (2认同)