2012-01-26 63 views
2

我有一个线程安全的可观察集合替换,我想为它编写一个单元测试。为了避免误报,我试图编写一个多线程测试,证明一个对象无法添加到ObservableCollection>中,因此我可以将其与我的交换,并看它变绿。我无法让这个测试失败(使用NUnit)。如何编写ObservableCollections的线程亲和性的失败测试

没有特定的顺序我试过到目前为止:

  • 在不同的线程创建的收集和更新当前
  • 创建当前线程的收集和更新上的备用
  • 使用不同的线程机制
    • 的ThreadStart
    • 调度
    • BackgroundWorker的
  • 使用不同的公寓指出
    • STA和MTA的所有组合在测试本身和/或一个或两个线程
  • 创建一个WPF窗口来收集和手动操作分派器框架以模拟运行时环境。

自定义集合本身在实际代码中工作正常,所以现在更多的是学术活动而不是任何事情;我穿的信心已经动摇:)

+1

您是否试图让标准可观察性在多线程场景中失败? – 2012-01-26 23:04:59

回答

4

你想测试的东西,是不是有...

没有理由为这个测试失败,因为ObservableCollection<T>类本身没有线程亲和力。它不是线程安全的,但它意味着如果您在没有正确锁定的情况下在多线程场景中使用它,这种行为将是不可预测的; ObservableCollection<T>中没有任何内容会显式抛出异常,如果你这样做。

然而,CollectionView确实有螺纹的亲和力,这就是为什么你不能从项目不同的线程添加到ObservableCollection<T>是否有连接到它(发生,例如一个CollectionView,当您将ItemsControl绑定到集合)。但它是抛出一个异常,而不是ObservableCollection<T>CollectionView ...

看看下面的代码:

var list = new ObservableCollection<string>(); 
// var view = CollectionViewSource.GetDefaultView(list); 
ThreadPool.QueueUserWorkItem(_ => list.Add("foo")); 

它的执行没有抛出异常,但如果你取消注释行创建CollectionView,它将抛出一个NotSupportedException

这种类型的CollectionView不支持从一个线程从调度线程不同其 SourceCollection变化。

+0

啊......这清除了一些东西,谢谢。我接受了这个答案,因为它提供了一种获得我期望的行为的途径(无论是否有效),以及对真正发生的事情的极好解释。 – JRoughan 2012-01-27 01:08:42