#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, вы не можете добавлять или удалять элементы из другого потока, даже если коллекция связана с помощью привязки!