IDisposable.Dispose() 实现应该是幂等的吗?
Microsoft.NET 框架提供了 IDisposable 接口,该接口需要实现 void Dispose() 方法。其目的是允许手动或基于范围释放 IDisposable 实现可能已分配的昂贵资源。示例包括数据库集合、流和句柄。
我的问题是,Dispose()
方法的实现是否应该是幂等的 - 当在同一实例上多次调用时,该实例仅被“处置”一次,并且后续调用不会抛出异常例外情况。在 Java 中,大多数具有类似行为的对象(我再次想到流和数据库连接作为例子)对于它们的 close()
操作来说都是幂等的,这恰好是 >Dispose()
方法。
然而,我个人使用 .NET(尤其是 Windows 窗体)的经验表明,并非所有实现(.NET 框架本身的一部分)都是幂等的,因此对这些实现的后续调用会抛出ObjectDisposeException
。这真的让我困惑于如何实现一次性对象的实现。该场景是否有一个通用的答案,或者它是否取决于对象的具体上下文及其用法?
The Microsoft.NET framework provides the IDisposable
interface which requires an implementation of void Dispose()
method. Its 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,应该如此。不知道它会被调用多少次。
来自 MSDN 上的实现 Dispose 方法:
具有良好 IDispose 实现的对象将具有一个布尔字段标志,指示它是否已被释放,并且在后续调用中不执行任何操作(因为它已被释放)。
Yes, it should. There is no telling how many times it will be called.
From Implementing a Dispose Method on MSDN:
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).是的,还要确保在对象已被释放的情况下调用该类的其他方法时正确响应。
Yes, also make sure the other methods of the class respond correctly when they are called when the object has already been disposed.
来自 MSDN:
From MSDN:
就个人而言 - 是的 - 我总是使 Dispose() 幂等。
在给定应用程序中对象的通常生命周期中,这可能是不必要的——从创建到处置的生命周期可能是确定性的并且是众所周知的。
然而,同样地,在某些应用中它可能不那么清晰。
例如,在装饰器场景中:我可能有一个一次性对象 A,由另一个一次性对象 B 装饰。我可能想显式处置 A,但 B 上的 Dispose 也可以处置它包装的实例(想想:流)。
鉴于使 Dispose 幂等性相对容易(即,如果已经处置,则不执行任何操作),不这样做似乎很愚蠢。
Personally - Yes - I always make Dispose() idempotent.
During the usual life-cyle of an object in a given application it may not be necessary - the life-cyle from creation to disposal may be deterministic and well known.
However, equally, in some applications it might not be so clear.
For example, in a decorator scenario: I may have a disposable object A, decorated by another disposable object B. I may want to explicitly dispose A, and yet Dispose on B may also dispose the instance it wraps (think: streams).
Given it is relatively easy to make Dispose idempotent (ie if already disposed, do nothing), it seems silly not to.