C# 什么时候可以';您不能在终结器/IDisposable上使用SafeHandle吗?

C# 什么时候可以';您不能在终结器/IDisposable上使用SafeHandle吗?,c#,dispose,idisposable,finalizer,C#,Dispose,Idisposable,Finalizer,当看到整个finalizer/IDisposable问题时,通常会看到,在结束了所有冗长的描述之后,会有一些类似于“LOL我所说的实际上是无用的,你应该使用SafeHandle来代替再见!” 因此,我想知道在什么情况下SafeHandle不适合,因此您必须求助于终结器/IDisposable旧方法 什么时候不能在终结器/IDisposable上使用SafeHandle 显而易见的答案是,安全手柄有很多优点 但是ReleasHandle()中的代码必须符合。它可以(不应该)调用可能抛出或锁定的代码

当看到整个finalizer/IDisposable问题时,通常会看到,在结束了所有冗长的描述之后,会有一些类似于“LOL我所说的实际上是无用的,你应该使用SafeHandle来代替再见!” 因此,我想知道在什么情况下SafeHandle不适合,因此您必须求助于终结器/IDisposable旧方法

什么时候不能在终结器/IDisposable上使用SafeHandle

显而易见的答案是,安全手柄有很多优点

但是
ReleasHandle()
中的代码必须符合。它可以(不应该)调用可能抛出或锁定的代码。因此,如果您的清理更复杂且“不可靠”,您仍然必须使用终结器/析构函数


但对于(操作系统)句柄,您可以而且应该始终使用安全句柄

显然,当您正在包装的非托管资源不是通过句柄获取时。这是罕见的,但并非闻所未闻。一个例子是用C++/CLI代码编写包装器,通常用来封装一个C++ C++类。资源就是内存。非托管类


然而,您可以花一辈子的时间编写托管代码,而从不编写终结器。终结器属于框架类。

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

但是,某些类型的资源可能会受益于具有终结器,即使它们需要执行受约束执行区域内不允许的操作。终结器在后台线程负责操作对象,并且主应用程序持有对象,而该对象又持有对真实对象的引用的情况下可能很有用。主应用程序的引用保持对象上的终结器可能会向后台线程发出信号,表示不再需要它所维护的对象。必须小心地发送此类信号,以确保它不会中断终结器线程,但如果小心地发送,将其放在终结器中可能会有所帮助,即使CER中不允许这样做