2011-11-13 12 views
4

当看到整个终结器/ IDisposable问题时,通常会看到,最后,在所有长描述之后,会出现“LOL我所说的实际上没用的含义,你应该使用SafeHandle而不是再见!“ 所以我想知道SafeHandle不适合什么情况,这样你不得不求助于终结器/ IDisposable旧的方式?何时不能在Finalizer/IDisposable上使用SafeHandle?

回答

3

很明显,当您要封装的非托管资源不是通过句柄获取的。这是罕见的,但并不是闻所未闻的。一个例子是在C++/CLI代码中编写包装,通常是为了包装一个本地C++类。资源就是内存。非托管类。然而,你可以花费一个职业写托管代码和永远不会写一个终结器。终结器属于框架类。

3

何时不能在Finalizer/IDisposable上使用SafeHandle?

显而易见的答案是几乎从不,Safehandles提供了很多优势。

ReleasHandle()内的代码必须确认Constrained Execution Region (CER)的限制。它可以(应该)不会调用可能抛出或锁定的代码。所以如果你的清理更加复杂和'不可靠',你仍然需要使用Finalizer /析构函数。

但是对于(OS)句柄,您可以并且应该始终使用SafeHandle。

0

许多类型的非托管资源可以通过在句柄上使用简单的API调用来满足其清理责任。这些资源可能(并且通常应该)被有效地封装在SafeHandle中。一些其他类型的非托管资源(例如由长期出版商持有的事件订阅)具有清理责任,通过终结器不能很好地处理。如果语义无用的强引用使被遗弃的对象保持活动状态,并且可能无法使用必须由创建它们的线程清理的资源,则终结器可能无用。无需为此类资源编写自定义终结器,因为没有终结器类型会消除确保它们确定处置的绝对必要性。

然而,即使某些类型的资源需要执行在受约束的执行区域内不允许的事情,也可以从终结器中获益。在后台线程负责操作对象以及主应用程序拥有一个对象的情况下,终结器可能非常有用,该对象反过来持有对真实对象的引用。主应用程序的引用保存对象上的终结器可能会向后台线程发出信号,表明它所维护的对象不再需要。这样的信号必须小心谨慎,以确保它不会中断终结器线程,但是如果小心处理,即使在CER中不允许,也可以将它放入终结器中。

相关问题