Мое приложение WPF структурировано с помощью шаблона MVVM. ViewModels свяжется асинхронно с сервером, и когда запрошенные данные будут возвращены, обратный вызов в ViewModel инициирован, и он сделает что-то с этими данными. Это будет работать на потоке, который не является Потоком UI. Иногда эти обратные вызовы включают работу, которая должна быть сделана на потоке UI, таким образом, мне нужен Диспетчер. Это могло бы быть вещами, такими как:
Я стараюсь избегать последнего, но две первых точки здесь я нахожу, чтобы быть разумными вещами для ViewModels, чтобы сделать. Так; это должно хорошо сделать, чтобы ViewModels содержал Диспетчера, чтобы смочь Вызвать команды для потока UI? Или это считают плохой практикой? И почему?
Поскольку ObservableCollection должен быть обновлен в потоке, которому он принадлежит (при условии, что приложение с графическим интерфейсом пользователя), а ObservableCollections должны быть частью ViewModel, то есть очевидный случай, когда ViewModel имеет Dispatcher.
Я не вижу, чтобы это было частью Модели.
Я согласен с kyoryu и хотел бы отметить, что он создает зависимость только от лоббаратемы ServiceModel (который у вас уже есть), а не от самого представления, поэтому есть очень мало возражений против этой конструкции.
Вчера я пробовал кое-что с WPF, простой виртуальной машиной и потоками и пришел к выводу, что мне абсолютно необходимо передать диспетчер на виртуальную машину.
В идеале ViewModel
должен быть полностью независимым от используемой технологии пользовательского интерфейса. Теоретически мы должны иметь возможность повторно использовать его для Windows Forms (если мы немного расширим элементы управления Windows Forms для поддержки лучшего связывания), для веб-страниц (Я представляю здесь некий причудливый механизм, который скомпилирует ViewModel
также в Javascript ) и для любых будущих технологий. Не все эти технологии будут использовать модель Dispatcher
.
Тем не менее, я считаю прагматическим компромиссом включение Dispatcher
в ViewModel
в настоящее время. В моем базовом классе ViewModel
я проверяю текущий Dispatcher
:
protected override void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (Deployment.Current.Dispatcher == null || Deployment.Current.Dispatcher.CheckAccess())
{
base.OnPropertyChanged(sender, e);
}
else
{
Deployment.Current.Dispatcher.BeginInvoke(() => base.OnPropertyChanged(sender, e));
}
}
Конечно, у меня все еще есть зависимость от System.Windows
, ну да ладно. : ->