【发布时间】:2011-01-24 03:36:25
【问题描述】:
我有一个 MVVM-lite 应用程序,我希望它可以进行单元测试。该模型使用 System.Timers.Timer,因此更新事件在后台工作线程上结束。这个单元测试很好,但在运行时抛出了 System.NotSupportedException “这种类型的 CollectionView 不支持从与 Dispatcher 线程不同的线程对其 SourceCollection 的更改。”我曾希望 MVVM-lite 类 Threading.DispatcherHelper 能解决问题,但调用 DispatcherHelper.CheckBeginInvokeOnUI 会导致我的单元测试失败。这是我在视图模型中最终得到的代码
private void locationChangedHandler(object src, LocationChangedEventArgs e)
{
if (e.LocationName != this.CurrentPlaceName)
{
this.CurrentPlaceName = e.LocationName;
List<FileInfo> filesTaggedForHere = Tagger.FilesWithTag(this.CurrentPlaceName);
//This nextline fixes the threading error, but breaks it for unit tests
//GalaSoft.MvvmLight.Threading.DispatcherHelper.CheckBeginInvokeOnUI(delegate { updateFilesIntendedForHere(filesTaggedForHere); });
if (Application.Current != null)
{
this.dispatcher.Invoke(new Action(delegate { updateFilesIntendedForHere(filesTaggedForHere); }));
}
else
{
updateFilesIntendedForHere(filesTaggedForHere);
}
}
}
private void updateFilesIntendedForHere(List<FileInfo> filesTaggedForHereIn)
{
this.FilesIntendedForHere.Clear();
foreach (FileInfo file in filesTaggedForHereIn)
{
if (!this.FilesIntendedForHere.Contains(file))
{
this.FilesIntendedForHere.Add(file);
}
}
}
我确实在http://kentb.blogspot.com/2009/04/mvvm-infrastructure-viewmodel.html 中尝试过这个技巧,但是对 Dispatcher.CurrentDispatcher 的 Invoke 调用在单元测试期间未能运行,因此它失败了。这就是为什么如果运行是在测试中而不是在应用程序中,我会直接调用辅助方法。
这不可能 - ViewModel 不应该关心它是从哪里调用的。谁能明白为什么 Kent Boogaart 的调度程序方法和 MVVM-lite DispatcherHelper.CheckBeginInvokeOnUI 在我的单元测试中都不起作用?
【问题讨论】:
标签: multithreading mvvm mvvm-light dispatcher