6

为了在所有主要公开方法的开头 bool disposed有条件地抛出 an ,在其他线程安全类型上跟踪经典字段是否有任何意义?ObjectDisposedException

我在网上的一些地方看到过这种模式推荐,但我不确定作者是否正确使用它,所以这个问题假设他们是。

在这种情况下,似乎确保disposed条件在条件评估之外为真的唯一方法是在每个暴露成员的整个主体上使用同步机制,例如 lock(),包括 Dispose(bool) 方法。这不会使类型再次有效地单线程吗?

如果这是真的,那么使用它就没有意义了,因此您不能在某些 IDisposable 实现中依赖 ObjectDisposedException 机制——那么如果没有必要,我们为什么还要使用这种机制呢?

====

我猜 IDisposable 和 ObjectDisposedException 只是不适合线程安全类型。

4

4 回答 4

4

Perhaps a more efficient way of making a threadsafe object not become disposed while a method is running is to use a ReaderWriterLockSlim. Have all the public methods obtain a read lock while executing and release it when they're done. Have Dispose obtain a writer lock. It will wait till all the other methods are done before it obtains it's write lock. It then sets isDisposed inside the write lock which it exclusively holds. Any calls to public methods after Dispose is done can see isDisposed and throw the ObjectDisposedException.

ReaderWriterLockSlim

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

于 2010-02-11T18:39:17.517 回答
3

如果您的对象的行为在它已经被释放后会有所不同,并且它很可能会在它被释放后被使用,那么您需要跟踪这一点。ObjectDisposedException如果对象已经被释放并且你没有先检查,那么抛出比抛出任何随机异常要好。

于 2010-02-11T19:14:44.380 回答
0

如果有可能在释放对象时调用方法,则方法的语义应定义为在已释放对象上调用它不会造成任何问题。在可能存在或不存在问题的情况下,应该使用“尝试/执行”模式。如果 Microsoft 在 Control.BeginInvoke 中遵循此原则,则将同时存在“Control.BeginInvoke”和“Control.TryBeginInvoke”;后者将被明确定义为返回 false 并且如果控件在操作入队之前被释放(请注意,返回 true 的 Control.BeginInvoke 不能保证控件不会在操作实际运行之前被释放)。这种模式在显示更新场景中非常有用:如果没有释放控件,我希望它的更新程序运行;但是,如果它在更新例程运行之前被处理掉,那么更新将变得毫无意义,并且它无法运行几乎不是问题。

于 2011-07-29T20:37:13.527 回答
0

鉴于“Disposed”布尔值仅在一个地方更新,并且调用者在调用 Disposed 后使用该对象是一个错误。

我认为在调用 Dispose 之后“大部分时间”抛出 ObjectDisposedException 就足够了。我认为 ObjectDisposedException 是一个调试助手,而不是调用者应该捕捉的东西。

于 2010-08-19T08:35:42.663 回答