Task parallel library INotifyPropertyChanged НЕ генерирует исключение?

#wpf #inotifypropertychanged #task-parallel-library

#wpf #inotifypropertychanged #task-parallel-library

Вопрос:

У меня есть проект wpf, в котором я использую INotifyPropertyChanged для свойства, которое привязывается к текстовому полю. Я обновляю это значение в другом потоке, используя task (TaskParallelLibrary). Он обновляется правильно и НЕ генерирует исключение. Я думал, что это вызовет исключение, потому что оно выполняется в фоновом потоке, а не в потоке пользовательского интерфейса. Конечно, он генерирует исключение, если я напрямую использую элемент пользовательского интерфейса. Итак, механизм привязки INotifyPropertyChanged автоматически выполняет отправку в поток пользовательского интерфейса?

Вот мой код со свойством.

 private string _textProperty = "";
    public string TextProperty
    {
        get
        {
            return _textProperty;
        }
        set
        {
            if (_textProperty != value)
            {
                _textProperty = value;
                NotifyPropertyChanged("TextProperty");
            }
        }
    }
  

и мое создание задачи

 var task = new Task(() =>
        {
            TextProperty = "ABCD"; // Works.
            // txtBox.Text = "ABCD"; // Throws an exception.
        });
        task.Start();
  

и текстовое поле в XAML <TextBox Name="txtBox" Text="{Binding TextProperty}"/>

Ответ №1:

Я думал, что это вызовет исключение, потому что оно выполняется в фоновом потоке, а не в потоке пользовательского интерфейса.

WPF позволяет установить привязанное значение в фоновом потоке. Он обработает маршалинг для потока пользовательского интерфейса для вас.

Имейте в виду, однако, что это не работает для элементов коллекции. Например, если вы хотите добавить к ObservableCollection<T> который связан, вам придется выполнить маршалирование обратно в поток пользовательского интерфейса. Однако существуют различные обходные пути, которые могут облегчить это, если требуется. Обратите внимание, что это поведение изменяется в WPF 4.5, что упростит многопоточную разработку в WPF в будущем.

Комментарии:

1. 1. Интересная ссылка на WPF 4.5. Похоже, они разобрались с некоторыми вещами, которые мне не нравятся в WPF в настоящее время.

2. @Reed у вас есть удобная ссылка на то, как wpf маршалирует обновление для вас?

Ответ №2:

Привязка к отдельным свойствам не привязана к потоку. Вы можете сделать это без проблем, привязка сделает необходимое для вас.
Однако будьте осторожны, это только для привязок отдельных свойств. Если у вас есть, например, ObservableCollection, вы не можете добавлять или удалять элементы из другого потока, даже если коллекция связана с помощью привязки!