是的,暂时关注 MVVM,有少数场景可能会发生线程化:
像往常一样,为简单起见,我们有一个 Model 类、ViewModel 类和 View 类。
该模型有一个 Collection 和一个字符串属性。
1)用户触发长时间运行的后台任务。 View 触发 ViewModel。可以通过 ViewModel 轻松管理,例如 BackgroundWorker
2)线程更新Model,ViewModel通知Model的变化。
之前我们讨论过使用 INotifyChanged 来通知从 Model 到 ViewModel 的更改。 DependencyProperty 系统似乎为您将这些编码到正确的线程。
对于 ObservableCollections 这不起作用。因此,我的模型的公开面应该是单线程的(不喜欢,为什么模型应该知道线程)还是我会在 ViewModel 中复制模型的某些部分(例如上面的集合)以确保对正确的线程?
我想我已经回答了我自己的问题。也许不是。我的模型确实知道线程,所以也许使用 Colin 早些时候提出的 IMarshalInvoker 想法将它们标记回来只是礼貌?
我的一些问题是我认为 MVVM 是另一种 MVC 变体,从历史上看,我很乐意互换使用 MVP、MP、MVC 等术语,因为我知道什么与 GUI 技术(通常是 winforms)一起使用V端。当我说 MVVM 时,我专门寻找有关 WPF 和 WPF 特定弱点的实用建议。我希望这能解释我的问题的性质以及我问这些问题的原因。
请您参考如下方法:
我认为在你的模型中全力以赴并以 ObservableCollection 的形式实现集合不是一个好主意。 ,因为这会以仅对 WPF 有用的方式“污染”您的模型。INotifyPropertyChanged没关系,因为:
所以,我建议不要让你的模型知道线程。让您的 ViewModel 了解线程,如下所示:
class Model {
List<Widget> Widgets { get; private set; }
}
class ModelViewModel {
ObservableCollection<Widget> Widgets { get; private set; }
ModelViewModel(Model model) {
this.Widgets = new ObservableCollection<Widget>(model.Widgets);
}
}
如果
Widget是引用类型并实现
INotifyPropertyChanged (这将是大约 100% 的时间),这可以让你大部分时间:
model本身并将立即反射(reflect)绑定(bind) 仍然存在无法对
model 进行集合更新(添加和删除项目)的问题直接地。但是可以这样安排:
ModelViewModel(Model model) {
this.Widgets = new ObservableCollection<Widget>(model.Widgets);
this.Widgets.CollectionChanged += this.PropagateChangesToModel;
}
void PropagateChangesToModel(object sender, NotifyCollectionChangedEventArgs e) {
// do what the name says :)
}
最后,你需要使
ObservableCollection从工作线程更新时玩得很好。这是 WPF 的一个非常常见的问题,我建议您引用这个问题的答案以获得解决方案:
ObservableCollection and threading .




