2010-02-11 51 views
6

为了有条件地在所有主要公开方法的开头部署ObjectDisposedException,是否有任何要跟踪其他线程安全类型的经典bool disposed字段?IDisposable,ObjectDisposedException和线程安全类型

我见过这种模式在网上几个地方推荐,但我不知道作者是否正确使用它,所以这个问题假设他们是。

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

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

====

我想了IDisposable和的ObjectDisposedException只是不一起去的线程安全的类型。

+0

另请参阅:http://stackoverflow.com/questions/170028/how-would-you-simplfy-entering-and-exiting-a-readerwriterlock – 2010-02-11 21:02:57

回答

4

也许一个更有效的方法使用ReaderWriterLockSlim时,使一个线程安全的对象不会被丢弃。让所有公共方法在执行时获得读锁,并在完成后释放它。有Dispose获得作家锁定。它会等到所有其他方法完成后才会获得写入锁定。然后在它独占的写入锁内设置isDisposed。在Dispose完成后,任何对公共方法的调用都可以看到isDisposed并抛出ObjectDisposedException

ReaderWriterLockSlim

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

+0

很酷的想法。有样品?没有在ReaderWriterSlimLock上找到文档。这是你以前见过的东西,还是你刚才头脑风暴的东西? – 2010-02-11 19:03:53

+0

只是头脑风暴,但我认为它应该适合您的要求。我在原来的答案中拼错了它,它是'ReaderWriterLockSlim'。我添加了一个MSDN文档的链接。 – 2010-02-11 19:10:16

+0

实际上,这几乎可以工作,除了FXcop正确地指出ReaderWriterLockSlim实现了IDisposable并且应该与对象资源的其余部分一起处理。所以一旦调用了dispose,我将不再能够获得读锁,以便测试该对象是否已被处置。 – 2010-02-12 23:49:21

3

如果你的对象的行为会有所不同,如果它已经被设置,如果它很可能是它被安置后,将被使用,那么你需要保持跟踪这个。抛出ObjectDisposedException比抛出任何随机异常更好,如果对象已经处理并且不首先检查将发生。

+0

是的,但这个问题是关于如何在多线程场景中确定地抛出ObjectDisposedException。 – 2010-02-15 19:25:45

+0

@Jason:在这种情况下,编辑你的问题说出来。 – 2010-02-15 22:35:39

0

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

我认为在Dispose被调用后“大部分时间”抛出ObjectDisposedException已经足够了。我将ObjectDisposedException看作是调试帮助程序,而不是调用程序应该捕获的东西。

0

如果在处理对象时有可能调用某个方法,则应该以这样的方式定义该方法的语义,即在处置对象上调用该方法不会造成任何问题。在可能或不可能有问题的情况下,应该使用“尝试/做”模式。如果微软在Control.BeginInvoke中遵循了这个原则,就会有一个“Control.BeginInvoke”和一个“Control.TryBeginInvoke”;后者将被明确定义为返回false,如果控件在行为排队之前处理,则不做任何事情(请注意,Control.BeginInvoke返回true不能保证控件在实际运行之前不会被处理)。这种模式在显示更新场景中非常有用:如果控件不处理,我希望它的更新例程运行;如果它在更新例程运行之前被丢弃,那么更新将变得没有意义,并且其失败并不会成为问题。