Визуальное обновление пользовательского интерфейса при выполнении дорогостоящей операции в потоке пользовательского интерфейса.

В моем приложении WPF мне нужно выполнить дорогую операцию в потоке пользовательского интерфейса (назовем это ExpensiveUIOperation()), и я хочу постоянно обновлять пользовательский интерфейс для отслеживания его прогресса.

Чтобы отслеживать прогресс, у меня просто есть TextBlock, чья Text свойство связано с целочисленным свойством зависимости PercentageComplete, В течение ExpensiveUIOperation() Я просто устанавливаю значение PercentageComplete как требуется.

Теперь я достаточно разбираюсь в потоках, чтобы знать, что если я просто ExpensiveUIOperation() в моем потоке пользовательского интерфейса, что TextBlock не будет обновляться, так как поток пользовательского интерфейса будет заблокирован, останавливая любые обновления интерфейса.

И поэтому я подумал, что могу сделать это асинхронно, как это:

Dispatcher.BeginInvoke(new Action(ExpensiveUIOperation), DispatcherPriority.Background);

Но это все еще не работает. Текстовый блок визуально не обновляется до завершения операции.

Есть ли способ сделать это?

К сожалению, в этой ситуации я не могу использовать фоновый поток, поскольку операция интенсивно использует объекты, принадлежащие потоку пользовательского интерфейса.

2 ответа

Решение

Вы застряли, операции пользовательского интерфейса должны выполняться в потоке пользовательского интерфейса, и пока это происходит, никаких обновлений пользовательского интерфейса не произойдет. Вы могли бы сделать эквивалент Application.DoEvents в WPF, создавая новый диспетчерский фрейм ( http://dedjo.blogspot.com/2007/08/how-to-doevents-in-wpf.html), но это опасно, вы поймете пользовательский интерфейс в середине обновлений и не очень хорошая вещь.

Действительно ли дорогостоящая операция пользовательского интерфейса требует интенсивной работы процессора и только пользовательского интерфейса? Ничего такого, что можно сделать с графом объектов модели представления и затем, наконец, связать с пользовательским интерфейсом, например?

К сожалению, в этой ситуации я не могу использовать фоновый поток, поскольку операция интенсивно использует объекты, принадлежащие потоку пользовательского интерфейса.

Это не является достаточной причиной для злоупотребления таким потоком пользовательского интерфейса. Используйте Dispatcher при доступе к этим элементам (см. Справочник по модели протектора) или правильно привязайте свое представление к соответствующим свойствам, и вам даже не нужно будет делать это, поскольку обновления помещаются в очередь внутри пользовательского интерфейса.

Другие вопросы по тегам