如果IDisposable.Dispose()实现幂等?IDisposable、Dispose

2023-09-04 02:33:40 作者:爱他们的时候我们像条狗

该Microsoft.NET框架提供了的IDisposable 接口,需要无效的Dispose()方法的实现。它的目的是使手动,或范围基剥离的的IDisposable 的实施可能已经分配昂贵的资源。例子包括数据库集合,溪流和把手。

我的问题是,如果的Dispose()方法的实现幂等 - 当在同一实例调用一次以上,该​​实例被处置只有一次,而后续调用没有抛出异常。在Java中,最有类似的行为(再次流和数据库连接,我想起为例)的对象是幂为他们的关闭()运行,这恰好是模拟为的Dispose()方法。

不过,我个人的经验与.NET(和Windows窗体尤其是),表明并非所有的实现(是的的.NET框架本身的一部分)是幂等,以便后续调用这些抛出一个的ObjectDisposedException 。这的确混淆了我如何一次性对象的实现要具体分析。是否有场景的共同答案,或者是它依赖于对象的具体上下文及其用法?

解决方案   

要实施的的Dispose()方法幂等

是的,它应该。有没有说服力了多少次会被调用。

从 MSDN上实现Dispose方法:

  

Dispose方法应该是调用多次,没有抛出异常。

有良好的执行 IDispose 的对象将有它是否已被处置已经和后续调用一个布尔字段标志,表示什么也不做(因为它已经被处理)。

The Microsoft.NET framework provides the IDisposable interface which requires an implementation of void Dispose() method. It's purpose is to enable manual, or scope-based releasing of expensive resources an IDisposable implementation may have allocated. Examples include database collections, streams and handles.

My question is, should the implementation of the Dispose() method be idempotent - when called more than once on the same instance, the instance to be 'disposed of' only once, and subsequent calls not to throw exceptions. In Java, most of the objects that have similar behavior (again streams and database connections come to my mind as examples) are idempotent for their close() operation, which happens to be the analogue for the Dispose() method.

However, my personal experience with .NET (and Windows Forms in particular), shows that not all implementations (that are part of the .NET framework itself) are idempotent, so that subsequent calls to these throw an ObjectDisposedException. This really confuses me on how a disposable object's implementation should be approached. Is there a common answer for the scenario, or is it dependent on the concrete context of the object and its usage?

解决方案

should the implementation of the Dispose() method be idempotent

Yes, it should. There is no telling how many times it will be called.

From Implementing a Dispose Method on MSDN:

a Dispose method should be callable multiple times without throwing an exception.

An object with a good implementation of IDispose will have a boolean field flag indicating if it has been disposed of already and on subsequent calls do nothing (as it was already disposed).