C#使用IDisposable还是SafeHandle?

时间:2011-10-18 03:59:58

标签: c# idisposable

我在C#中已经阅读了很多关于终结器和IDisposable的内容。当我终于从终结者和IDisposable的这种可怕的混乱中清楚地看到,突然之间,突然间,有这个SafeHandle的东西。 我的信念再次完全动摇了。我应该用什么?

3 个答案:

答案 0 :(得分:18)

SafeHandle仅在处理Win32 Interop调用时有用。在Win32中,大多数东西都由“句柄”表示。这包括Windows,Mutex等。因此.NET SafeHandle使用一次性模式来确保Win32句柄正确关闭。

因此,如果您正在使用Win32 Interop调用并获取Win32句柄,那么请使用SafeHandle。对于你自己的对象,你会坚持使用IDisposable和终结器。

答案 1 :(得分:5)

您可以/应该将SafeHandle用于任何可以表示为IntPtr的非托管资源,即Win32句柄,由非托管代码分配的内存等等。如果SafeHandle不合适,但您仍然需要处理非托管资源,请考虑将自己的类似SafeHandle的类继承自CriticalFinalizerObject

在所有其他情况下(即处理托管资源)实现IDisposable。在大多数情况下,您不需要终结器,大多数托管资源在调用终结器时将不可用,因此无需执行任何操作。

答案 2 :(得分:2)

在大多数情况下,我的建议是假装没有终结器这样的东西,但要100%确定创建的任何IDisposable对象都会被销毁。即使终结器以100%最佳方式编写,代码正确处理其一半对象并让终结器处理另一半的代码也不如正确处理其所有对象且不使用终结器的代码。虽然从来没有通过的终结器的性能影响确实不是太可怕,但终结器很难正确编写,如果他们的代码或使用它们的代码写得不完美,它们会导致Heisenbugs。此外,成功实施终结者通常需要创建一个或多个WeakHandles,其唯一目的是支持最终确定。

也许最终确定的安全网是值得的,但成本可能相当大,而且安全网不像人们想要的那样可靠。