线程安全一次性

时间:2014-02-06 15:03:28

标签: c# idisposable

处理IDisposable资源时,我需要确保线程安全。资源在内存中多次缓存。当条目从缓存中逐出时,我们会有一个调用Dispose()的回调。

因此,如果资源被缓存三次,我们将调用Dispose()三次。

IDisposable资源是否有责任确保线程安全或调用者?

4 个答案:

答案 0 :(得分:1)

实现IDisposable接口的类负责确保可以多次调用该方法而不抛出异常。

  

为了确保始终适当地清理资源,Dispose方法应该可以多次调用,而不会抛出异常。

http://msdn.microsoft.com/en-us/library/fs2xkftw(v=vs.110).aspx

在处理对象之后,因为对象被丢弃而失败的调用可能并且可能应该抛出ObjectDisposedException(以帮助将来调试)。如果外部对象在进行调用之前知道对象是否被处置是很重要的(因为对象是共享的),那么通常会添加一个指示对象状态的公共布尔属性(IsDisposed / Disposed)。 / p> 编辑:为了更清楚地回答这个问题的措辞,实现IDisposable的类应该实现线程安全,如果预期该类将在跨线程环境中使用。我发布的链接在页面底部显示了一个示例。

答案 1 :(得分:1)

要么

  1. 驱逐值并呼叫Dispose的系统必须使用同步来确保呼叫不重叠
  2. 对象本身必须以可以从多个线程安全地调用它的方式实现Dispose
  3. 这两个都是问题的完全有效的解决方案。哪一个更好将取决于您的系统。

    在所有其他条件相同的情况下,我会选择#2。我更喜欢让我的对象自给自足,并且需要尽可能少的帮助才能在他们设计的环境中成功执行。使其线程安全可以减少系统其他部分正确使用它所需的知识

答案 2 :(得分:0)

  

IDisposable资源是否有责任确保线程安全或调用者?

由调用者通过lock原语来保证线程安全,或者MonitorIDisposable与线程安全无关。这只是一个信号,表明对象的实例已准备好进行垃圾回收。

答案 3 :(得分:0)

答案取决于您要处置的对象是否符合指南

如果他们从IDisposable.Dispose

那里做了一些事情变得更简单了
  

如果多次调用对象的Dispose方法,则该对象必须忽略第一个之后的所有调用。如果多次调用Dispose方法,则该对象不得抛出异常。除了Dispose之外的实例方法可以在已经处理资源时抛出ObjectDisposedException。

因此,如果多次调用Dispose除了第一次调用之外没有任何效果,则只需要确保不要同时调用它们。这绝对应该是来电者的责任。


Stephen Cleary在CodeProject上撰写了一篇关于how to implement IDisposable的文章以及我认为非常有帮助的可能问题。

相关问题