MVVM и многопоточность - PullRequest
       3

MVVM и многопоточность

6 голосов
/ 05 января 2011

Правильно, придерживаясь фокуса MVVM на минуту, существует небольшое количество сценариев, где может происходить многопоточность:

Как обычно, для простоты у нас есть класс Model, класс ViewModel и класс View.Модель имеет коллекцию и строковое свойство.

1) Пользователь запускает длительную фоновую задачу.Просмотр триггеров ViewModel.Может легко управляться с помощью ViewModel, например, с помощью BackgroundWorker

2) Обновление потоков в модели, ViewModel, уведомляемая моделью об изменениях.

Ранее мы уже обсуждали использование INotifyChanged для уведомления об изменениях из модели в ViewModel.Система DependencyProperty, по-видимому, направляет их в нужный вам поток.

Для ObservableCollections это не работает.Следовательно, должно ли публичное лицо моей модели быть однопоточным (Не нравится, почему Модель должна знать о потоках), или я должен реплицировать некоторые части Модели (например, коллекцию выше) в ViewModel, чтобы гарантировать внесение изменений вправильная тема?

Я думаю, что вроде как ответил на свой вопрос.Возможно нет.Моя модель знает о потоках, так что, возможно, было бы вежливым возвращать их назад, используя идею IMarshalInvoker, предложенную ранее Колином?

Некоторые из моих проблем здесь заключаются в том, что я считаю MVVM еще одним вариантом MVC, и историческиЯ был счастлив использовать термины типа MVP, MP, MVC практически взаимозаменяемо, потому что я знал, что работает с технологией графического интерфейса (обычно winforms) на V-конце.Когда я говорю MVVM, я специально ищу практические советы о том, что работает для конкретных недостатков WPF и WPF.Я надеюсь, что это объясняет природу моих вопросов и почему я их задаю.

1 Ответ

6 голосов
/ 05 января 2011

Я не думаю, что это очень хорошая идея - полностью использовать и реализовать коллекции в вашей модели как ObservableCollection, поскольку это «загрязняет» вашу модель таким образом, что это полезно только для WPF.

INotifyPropertyChanged в порядке, потому что:

  • Есть много сценариев, в которых полезно умение «слушать».
  • Его можно использовать практически из любого кода .NET, а не только из WPF.
  • Это не доставит вам никаких хлопот, если вы хотите сериализовать вашу модель.

Итак, я предлагаю не , чтобы ваша модель знала о потоках. Сделайте так, чтобы ваша 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 и немедленно отразятся на привязках
  • Обновления в коллекции сразу отразятся на привязках

По-прежнему существует проблема, заключающаяся в том, что обновления коллекции (добавление и удаление элементов) не будут производиться непосредственно до 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 и threading .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...