MSDN 很好地记录了 BCL 类型的实例成员的线程安全性,但我从未真正看到过信息表明如何Dispose
的方法IDisposable
可以调用类型。
Is the Dispose
方法a)保证对所有类都是线程安全的,b)从不保证是线程安全的,c)保证对某些类是线程安全的(如果是这样,具体记录在哪里)?
最后,如果Dispose
方法保证是线程安全的,这是否意味着我必须在使用一次性资源的类中的每个实例方法周围放置一个锁?
侧面观点:我知道类型的终结器应该是线程安全的,因为垃圾收集在 .NET 中的工作方式(相当激进),并且它们可能会调用Dispose
方法。不过,我们先把这个问题放在一边。
线程安全和Dispose 的问题有些棘手。由于在许多情况下,一旦任何其他线程开始处置对象,任何线程可以合法地对对象做的唯一事情就是尝试处置它本身,因此乍一看似乎确保线程安全所需的唯一事情是在“dispose”标志上使用 Interlocked.Exchange,以确保一个线程的 Dispose 尝试发生,而另一个线程被静默忽略。事实上,这是一个很好的起点,我认为它应该是标准 Dispose 模式的一部分(CompareExchange 应该在密封的基类包装方法中完成,以避免每个派生类都需要使用自己的私有已处置标志)。不幸的是,如果考虑一下 Dispose 的实际作用,事情就会复杂得多。
Dispose 的真正目的不是对正在处置的对象执行某些操作,而是清理该对象所引用的其他实体。这些实体可能是托管对象、系统对象或完全其他的东西;它们甚至可能与被处置的对象不在同一台计算机上。为了使 Dispose 成为线程安全的,那些其他实体将允许 Dispose 在其他线程可能对它们执行其他操作的同时清理它们。有些对象可以处理这种用法;其他人则不能。
一个特别令人烦恼的例子:允许对象拥有带有非线程安全的RemoveHandler 方法的事件。因此,任何清理事件处理程序的 Dispose 方法都只能从与创建订阅的线程相同的线程中调用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)