IDisposable、ObjectDisposeException 和线程安全类型

发布于 2024-08-20 17:54:36 字数 481 浏览 9 评论 0原文

为了在所有主要公开方法的开头有条件地抛出 ObjectDisposeException ,是否有必要跟踪其他线程安全类型上的经典 bool Dispose 字段?

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

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

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

====

我猜 IDisposable 和 ObjectDisposeException 只是不能一起用于线程安全类型。

Is there any point in keeping track of the classic bool disposed field on an otherwise threadsafe type for the purposes of conditionally throwing an ObjectDisposedException at the beginning of all primary exposed methods?

I've seen this pattern recommended in a few places online but I'm not sure if the authors are using it correctly, so this question assumes that they are.

In such a scenario, it seems that the only way to ensure that the disposed condition is true beyond the condition's evaluation is to use a synchronization mechanism such as lock() over the entire body of each exposed member including the Dispose(bool) method. Wouldn't this make the type effectively single-threaded again?

And if this is true, then there'd be no point in using it, and therefore you can't rely on the ObjectDisposedException mechanism in some IDisposable implementations - so then why would we EVER employ this mechanism if it isn't necessary?

====

I guess IDisposable and ObjectDisposedException just don't go together for thread-safe types.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

意中人 2024-08-27 17:54:36

也许在方法运行时使线程安全对象不被释放的更有效方法是使用 ReaderWriterLockSlim。让所有公共方法在执行时获取读锁,并在完成后释放它。让 Dispose 获取写入器锁。它将等到所有其他方法完成后才获得写锁。然后,它在它独占的写锁中设置isDisposeDispose 完成后对公共方法的任何调用都可以看到 isDispose 并抛出 ObjectDisposeException

ReaderWriterLockSlim

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

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

亚希 2024-08-27 17:54:36

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

If the behavior of your object will be different if it is already disposed, and if it's likely that it will be used after it's been disposed, then you need to keep track of this. It's better to throw ObjectDisposedException than to throw whatever random exception that will occur if the object is already disposed and you don't check first.

甩你一脸翔 2024-08-27 17:54:36

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

我认为在调用 Dispose 后“大多数时候”抛出 ObjectDisposeException 就足够了。我认为 ObjectDisposeException 是一个调试助手,而不是调用者应该捕获的东西。

Given that the "Disposed" boolean is only updated in one place, and it is a bug in your caller to use the object after they had called Disposed.

I think it is good enough to throw ObjectDisposedException "most of the time" after Dispose has been called. I see ObjectDisposedException as being a debug helper not thingthing that a caller should be catching.

凝望流年 2024-08-27 17:54:36

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

If there is a possibility of a method being called while an object is disposed, the method's semantics should be defined in such a way that calling it on a disposed object will pose no problem. In cases where there may or may not be a problem, one should use the "try/do" pattern. If Microsoft had followed this principle with Control.BeginInvoke, there would be both a "Control.BeginInvoke" and a "Control.TryBeginInvoke"; the latter would be explicitly defined as returning false and doing nothing if a control was disposed prior to the action being enqueued (note that Control.BeginInvoke returning true would not guarantee that the control wouldn't get disposed before the action was actually run). This pattern would be very useful in things like display-update scenarios: if a control isn't disposed, I want its update routine to run; if it gets disposed before the update routine runs, however, the update will become moot and its failure to run would hardly be a problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文