Потоки пользовательского интерфейса с ViewModels - PullRequest
6 голосов
/ 21 января 2010
  • Коллекции, связанные в представлении WPF, должны обновляться в потоке пользовательского интерфейса.
  • ViewModel предоставляет коллекцию
  • Поэтому, когда коллекция в ViewModel изменена, это должно быть сделано в потоке пользовательского интерфейса
  • Лучше всего держать ViewModels в неведении о View и, возможно, о таких деталях, как Dispatcher.

Как лучше всего решить эту проблему, сохраняя возможность проверки модели представления?

Ответы [ 4 ]

3 голосов
/ 21 января 2010

Один из вариантов здесь - выставить SynchronizationContext , который можно использовать из ViewModel. Это механизм, который класс BackgroundWorker использует для синхронизации с пользовательским интерфейсом, не вводя зависимости от WPF или Windows Forms и позволяя ему работать с несколькими технологиями.

Это позволит вам выполнить маршалинг обратно в поток пользовательского интерфейса, не обращаясь к самому пользовательскому интерфейсу, включая Dispatcher.

1 голос
/ 23 января 2010

Это довольно хорошо решается путем абстрагирования всей вашей логики добавления / удаления / обновления наблюдаемых коллекций + любой другой сложной логики, которая в вашем сценарии встречается в разных потоках.

Этот класс контроллера может отвечать за обновление ViewModel (он может иметь ссылку на виртуальную машину по интерфейсу) в правильном потоке.

1 голос
/ 21 января 2010

Вы правы в том, что WPF дает нам Dispatcher для упрощения многопоточности; но если вы хотите разделить проблемы с шаблоном MVVM, вам необходимо реализовать другую стратегию потоков.

Я всегда находил класс BackgroundWorker более чем достаточным, чтобы удовлетворить это, отправляя обновления обратно в поток пользовательского интерфейса, чтобы вы могли обновить ObservableCollection в ВМ и распространить изменения в представлении. *

0 голосов
/ 21 января 2010

Один из вариантов - создать подкласс ObservableCollection, который переопределяет OnPropertyChanged и OnCollectionChanged и отправляет соответствующие события обратно в поток пользовательского интерфейса (через что-то вроде SynchronizationContext).

Это позволяет ViewModel быть более независимым, когда речь идет о многопоточности, а также значительно облегчает управление тестируемым кодом.

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