如何为 ObservableCollections 的线程亲和性编写失败测试
我有一个线程安全的可观察集合替换,我想为其编写单元测试。为了避免误报,我尝试编写一个多线程测试来证明对象无法添加到 ObservableCollection<> 中。不会失败,这样我就可以将它与我的交换并看着它变绿。我只是无法让这个测试失败(使用 NUnit)。
到目前为止,我尝试过的没有特定顺序:
- 在不同线程上创建集合并在当前线程上更新
- 在当前线程上创建集合并在备用线程上更新
- 使用不同的线程机制
- 线程启动
- 调度员
- 后台工作人员
- 使用不同的单元状态
- 测试本身和/或一个或两个线程上的 STA 和 MTA 的所有组合
- 创建一个 WPF 窗口来保存集合并手动操作 Dispatcher 帧以模拟运行时环境。
自定义集合本身在实际代码中运行良好,因此现在这更像是一项学术练习;我的线程信心已经动摇了:)
I have a thread safe observable collection replacement which I would like to write a unit test for. To avoid a false positive I'm trying to write a multi-threaded test that proves an object cannot be added to an ObservableCollection<> without failing so I can swap it with mine and watch it go green. I just cannot get this test to fail (using NUnit).
In no particular order I've so far tried:
- Creating the collection on a different thread and updating on current
- Creating the collection on the current thread and updating on an alternate
- Using different threading mechanisms
- ThreadStart
- Dispatcher
- BackgroundWorker
- Using different apartment states
- All combinations of STA and MTA on the test itself and/or one or both of the threads
- Creating a WPF Window to hold the collection and manipulating the Dispatcher frames manually to simulate a runtime environment.
The custom collection itself is working fine in real code so this is now more of an academic exercise than anything; My threading confidence has been shaken :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您正在尝试测试不存在的东西...
此测试没有理由失败,因为
ObservableCollection
类本身不具有线程亲和性。它不是线程安全的,但这只是意味着如果您在没有适当锁定的多线程场景中使用它,则行为将是不可预测的;如果您这样做,ObservableCollection
中没有任何内容会显式抛出异常。但是, CollectionView 类确实可以 具有线程关联性,这就是为什么您无法从不同的线程将项目添加到
ObservableCollection
(如果存在)CollectionView
附加到它(例如,当您将ItemsControl
绑定到集合时,就会发生这种情况)。但抛出异常的是CollectionView
,而不是ObservableCollection
...采用以下代码:
它执行时不会抛出异常,但如果取消注释该行创建
CollectionView
时,它会抛出NotSupportedException
:You're trying to test something that is not there...
There is no reason for this test to fail, because the
ObservableCollection<T>
class itself doesn't have thread affinity. It's not thread-safe, but it just means the behavior will be unpredictable if you use it in a multithread scenario without proper locking; there is nothing inObservableCollection<T>
that will explicitly throw an exception if you do this.However, the CollectionView class does have thread affinity, which is why you can't add items to an
ObservableCollection<T>
from a different thread if there is aCollectionView
attached to it (which happens, for instance, when you bind anItemsControl
to the collection). But it's theCollectionView
that throws an exception, not theObservableCollection<T>
...Take the following code:
It executes without throwing an exception, but if you uncomment the line that creates the
CollectionView
, it will throw aNotSupportedException
: