Безопасность потоков, списки, привязка и WPF - PullRequest
0 голосов
/ 06 августа 2010

У меня есть WPF ListView, который связан с коллекцией (List<T>).В настоящее время он обновляется из текущего потока, который работает нормально.

Я хочу переместить логику для обновления списка в поток, и я вижу некоторые потенциальные проблемы, касающиеся безопасности потока и связывания списка.Могу ли я быть уверен, что привязка не будет обновлена, если я не позвоню NotifyPropertyChanged?NotifyPropertyChanged блокирующий вызов или он просто добавляет его в очередь сообщений;в этом случае, безусловно, может быть условие, при котором я сообщаю ListView, что коллекция обновлена, но к тому времени, когда привязка обновится, я, возможно, изменю коллекцию в другом потоке, что вызовет исключение или завершит работу программы.

Каков наилучший метод для обеспечения безопасности потоков в таком сценарии?

Ответы [ 2 ]

1 голос
/ 06 августа 2010

INotifyPropertyChanged не является потокобезопасным и блокирует вызывающий поток.

Best?Это хороший вопрос.Я не знаю.Суть в том, что в тот или иной момент вызовы должны перенаправляться в поток пользовательского интерфейса.Когда вы делаете это?

Вы могли бы 1) подготовить все, а затем доставить его в поток пользовательского интерфейса, где пользовательский интерфейс затем обновляется.Или вы могли бы 2) реализовать INotifyPropertyChanged и сделать так, чтобы запуск этого события всегда происходил в потоке пользовательского интерфейса, или 3) вы могли бы сделать одно из нескольких разных действий.для пользовательского интерфейса, чтобы происходить все сразу (не по одному за раз, как вы могли бы получить, например, при добавлении отдельных элементов в ObservableCollection).Поэтому может быть целесообразно создать некоторые поточно-ориентированные базовые классы, которые реализуют INotifyProperty и CollectionChanged, и использовать их.

В фреймворке нет ничего, что могло бы сделать это для вас, к сожалению.

1 голос
/ 06 августа 2010

Вы можете выполнить обновление коллекции из Dispatcher.Invoke, чтобы избежать проблем с потоками:

void ThreadProc()
{
   window.Dispatcher.Invoke(() => {
      //UpdateList
   });
}
...