#.net #wpf #multithreading #data-binding
#.net #wpf #многопоточность #привязка данных
Вопрос:
Если значение свойства обновляется из рабочего потока (не пользовательского интерфейса), отразится ли это в элементе управления, который использует привязку данных и прослушивает изменение свойства?
Спасибо за проявленный интерес.
Комментарии:
1. Однако стоит отметить, что уведомления об изменении коллекции ObservableCollection не потокобезопасны (обновления коллекции необходимо вручную делегировать обратно потоку пользовательского интерфейса.)
Ответ №1:
WPF использует Dispatcher, так что все работает в одном потоке пользовательского интерфейса, но имеет параллелизм типа switch. И когда вы обновляете некоторый реквизит объекта зависимости, он фактически отправляет новое задание в очередь диспетчера. Когда это задание выполняется, оно выполняется в потоке пользовательского интерфейса и должным образом обновляет элементы управления. Но если вы попытаетесь получить доступ к элементам управления непосредственно из фонового потока, вы получите исключение.
Из-за этой реализации есть определенные крайние случаи. Например. даже если вы обновите prop в потоке пользовательского интерфейса, вы не можете ожидать, что элемент управления синхронно обновит его самостоятельно, чтобы отразить ваши изменения. Итак, если у вас есть xaml, подобный этому:
<TextBox x:name="tb" Text="{Binding Text"}/>
И код, подобный этому:
var model = new { Text = "aaa" };
tb.DataContext = model;
model.Text = "bbb";
Debug.Assert(tb.Text == "bbb");
Утверждение может завершиться ошибкой, поскольку обновление может пройти через диспетчер в следующей задаче. И он не будет обновляться, пока этот текущий вызов не будет завершен и управление не будет возвращено диспетчеру.
Ответ №2:
Да, это будет. Фактически, одно из основных преимуществ использования привязки данных WPF заключается в упрощении реализации именно этого сценария.