IDisposable.Dispose()实现应该是幂等的吗?

Iva*_*vov 22 .net c# memory-management idempotent

Microsoft.NET框架提供了IDisposable需要实现void Dispose()方法的接口.其目的是IDisposable实现可能已分配实施的昂贵资源的手动或基于范围的发布.示例包括数据库集合,流和句柄.

我的问题是,如果该Dispose()方法的实现是幂等的 - 当在同一个实例上多次调用时,该实例仅被"处置"一次,并且后续调用不会抛出异常.在Java中,大多数具有相似行为的对象(作为示例再次出现流和数据库连接)对于它们的close()操作是幂等的,这恰好是该Dispose()方法的模拟.

但是,我个人使用.NET(特别是Windows Forms)的经验表明,并非所有实现(它们都是.NET框架本身的一部分)都是幂等的,因此后续调用这些实现会引发争议ObjectDisposedException.这真的让我对如何处理一次性对象的实现感到困惑.该场景是否有共同的答案,还是取决于对象的具体上下文及其用法?

Ode*_*ded 20

应该是Dispose()方法的实施是幂等的

是的,它应该.没有人知道它会被召唤多少次.

从在MSDN上实现Dispose方法:

Dispose方法应该可以多次调用而不会抛出异常.

具有良好实现的对象IDispose将具有布尔字段标志,该标志指示它是否已经被处理掉并且在后续调用中什么也不做(因为它已经被处置).

  • 仅仅因为微软并不总是遵循自己的建议并不意味着你应该这样做. (7认同)

Ern*_*rno 7

是的,当对象已被处理时,还要确保在调用类时其他方法正确响应.

public void SomeMethod()
{
     if(_disposed)
     {
         throw new ObjectDisposedException();
     }
     else
     {
         // ...
     }

}
Run Code Online (Sandbox Code Playgroud)


Tho*_*que 5

来自MSDN:

允许多次调用Dispose方法而不抛出异常.第一次调用后,该方法应该不执行任何操作.

  • 为清楚起见,您可能应该包含下一个要点:"当资源已经处理时,从此类型的实例方法(除了Dispose)抛出一个ObjectDisposedException.此规则不适用于Dispose方法,因为它应该可以多次调用而不抛出一个例外." (3认同)