假设有一个实现IDisposable
接口并具有一些公共方法的类。
如果该类型的实例在多个线程之间共享,而其中一个线程可能会处理它,那么保证其他线程在已处理后不再尝试使用该实例的最佳方式是什么? 在大多数情况下,在对象被处理后,它的方法必须意识到这一点并抛出ObjectDisposedException
或者可能是InvalidOperationException
,或者至少通知调用代码执行了错误的操作。对于每个方法,特别是在检查它是否被处理时,我需要同步吗? 所有带有其他公共方法的IDisposable
实现都需要是线程安全的吗?
下面是一个例子:
public class DummyDisposable : IDisposable
{
private bool _disposed = false;
public void Dispose()
{
_disposed = true;
// actual dispose logic
}
public void DoSomething()
{
// maybe synchronize around the if block?
if (_disposed)
{
throw new ObjectDisposedException("The current instance has been disposed!");
}
// DoSomething logic
}
public void DoSomethingElse()
{
// Same sync logic as in DoSomething() again?
}
}
Finalize()
是从一个独立的GC线程中调用的。然而,只有当没有存活的引用对象时才会调用Finalize()
,因此线程安全性不应该是一个考虑因素。在MS最佳实践中,建议在Finalize()
内部调用Dispose,或者至少使用几乎相同的逻辑 - 参见链接。这可能导致在Finalize()
方法中调用线程安全意识代码。 - Ivaylo Slavov