我想要一种方法来打破IDisposable
您突然依赖的某些嵌套类现在实现的链条,IDisposable
并且您不希望该接口波及复合层。基本上,我通过'SubscribeWeakly()'IObservable<T>
对's的订阅很弱,我想在我离开时清理它们,以免泄漏包装器实例,以防万一永远不会触发。这就是动机,但我也将它用于其他事情。Observable
另一篇文章也有类似的问题,答案基本上表明您仍然可以访问终结器中的一次性用品。但是,您无法保证终结器的运行顺序,因此处置可能会出现问题。
因此,我需要一种方法来保证一次性用品保持活动状态,以便我可以调用Dispose()
我的终结器。所以我看了看GCHandle
,它允许 C++ 通过将它们及其聚合拉入应用程序句柄来保持(并保持活动状态)托管对象,以使它们保持活动状态,直到句柄被释放并且复合生命周期返回到 .NET 内存的控制经理。来自 C++,我认为类似于 的行为std::unique_ptr
会很好,所以我想出了类似于AutoDisposer
.
public class AutoDisposer
{
GCHandle _handle;
public AutoDisposer(IDisposable disposable)
{
if (disposable == null) throw new ArgumentNullException();
_handle = GCHandle.Alloc(disposable);
}
~AutoDisposer()
{
try
{
var disposable = _handle.Target as IDisposable;
if (disposable == null) return;
try
{
disposable.Dispose();
}
finally
{
_handle.Free();
}
}
catch (Exception) { }
}
}
在需要在资源消失时处理资源的类中,我只需分配一个像_autoDisposables = new AutoDisposer(disposables)
. 然后,这AutoDisposer
将在包含类的同时被垃圾收集器清理掉。但是,我想知道这种技术会出现什么问题。现在我能想到以下几点:
- 通过终结器对垃圾收集器产生额外开销
- .NET 的额外开销必须从托管内存中提取项目到应用程序句柄并返回它们
- 不可单元测试(我似乎无法预测资源何时返回到 .NET 进行内存管理。)
IDisposable
因此,如果我需要确定性地调用Dispose()
等等,我会谨慎使用它。
有人看到其他问题吗?这种技术甚至有效吗?