Ian*_*Ian 6 wpf multithreading mvvm
对,坚持MVVM焦点一分钟,有少数可能发生线程的场景:
像往常一样,为简单起见,我们有一个Model类,ViewModel类和View类.Model具有Collection和string属性.
1)用户触发长时间运行的后台任务.视图触发ViewModel.可以使用ViewWorker轻松地使用ViewModel进行管理
2)线程更新模型,ViewModel通过模型更改通知.之前我们已经讨论过使用INotifyChanged来通知从Model到ViewModel的更改.DependencyProperty系统似乎为您编组这些正确的线程.
对于ObservableCollections,这不起作用.因此,如果我的模型的公共面是单线程的(不喜欢,模型为什么要知道线程),或者我会在ViewModel中复制模型的某些部分(例如上面的Collection)以确保对模型进行修改正确的线程?
我想我已经回答了我自己的问题.也许不是.我的模型不知道线程,因此或许只有礼貌对待markshal回用科林早期酝酿的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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果Widget是一个引用类型和实现INotifyPropertyChanged(大约100%的时间),这会让你大部分时间:
model并立即反映绑定仍然存在无法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 :)
}
Run Code Online (Sandbox Code Playgroud)
最后,您需要通过ObservableCollection从工作线程更新来发挥良好作用.这是WPF的一个非常常见的问题,我将为您提供一个解决方案的答案:ObservableCollection和threading.