WedX - журнал о программировании и компьютерных науках

Почему Dispatcher.Invoke не запускает обновление пользовательского интерфейса?

Я пытаюсь повторно использовать UserControl, а также позаимствовать некоторую логику, которая отслеживает прогресс. Я постараюсь упростить вещи. MyWindow.xaml включает MyUserControl. MyUserControl имеет собственный индикатор выполнения (выполняется форматирование..., копирование файлов... и т. д.), и я хотел бы отразить этот прогресс где-нибудь в форме MyWindow. Но у пользовательского элемента управления есть некоторая логика, которую я не совсем понимаю. Я читал и читал, но я все еще не понимаю Dispatcher. Вот сводка логики в пользовательском элементе управления, который обновляет ход выполнения.

this.Dispatcher.Invoke(DispatcherPriority.Input, (Action)(() =>
{
   DAProgressIndicator = InfiniteProgress.AddNewInstanceToControl(StatusGrid, new SolidColorBrush(new Color() { A = 170, R = 128, G = 128, B = 128 }), string.Empty);
                DAProgressIndicator.Message = MediaCardAdminRes.ActivatingCard;
                ActivateInProgress = true;
}));

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

   public bool ActivateInProgress 
   {
      get
      {
         return _activateInProgress;
      }
      set
      {
         _activateInProgress = value;
         if (ActivateInProgressHandler != null)
         {
            ActivateInProgressHandler(value);
         }
      }
   }

Я устанавливаю ActivateInProgressHandler в конструкторе MyWindow для следующего метода, который устанавливает свойство модели представления, используемое для собственного индикатора хода выполнения окна.

private void SetActivation(bool activateInProgress)
{
   viewModel.ActivationInProgress = activateInProgress;
}

Однако индикатор хода выполнения окна никогда не меняется. Итак, я убежден, что Dispatcher.Invoke делает что-то, чего я не понимаю. Если я помещу окно сообщения в метод SetActivation, поток заблокируется, а индикатор выполнения окна обновится. Я понимаю основные потоки, но вся эта штука с Dispatcher для меня в новинку. Что мне не хватает?

ОБНОВЛЕНИЕ: Кажется, теперь это работает. Оказывается, прогресс обновлялся так быстро, что никогда не отображался на экране. Но я все же хотел бы понять, почему был сделан Dispatcher.Invoke (это был существующий код, который я не писал). Почему содержимое действия не соответствует остальной части кода *.xaml.cs?

15.06.2010

  • Как вы обновляете индикатор выполнения в своем окне? Это должно быть сделано в отдельном потоке, но с использованием диспетчера. 15.06.2010

Ответы:


1

В вашем последнем абзаце дважды упоминаются потоки, что повышает вероятность того, что существует один или несколько фоновых потоков. Но поскольку вы не упомянули, какие потоки существуют в приложении, как они создаются, как взаимодействуют и т. д., я предполагаю, что на данный момент существует только один поток.

Если поток пользовательского интерфейса является единственным потоком, проблема очевидна: ваш поток пользовательского интерфейса занят выполнением текущей задачи, и ему не требуется время для отображения обновленного пользовательского интерфейса. Если это проблема, это, вероятно, исправит ее:

viewModel.ActivationInProgress = activateInProgress; 
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
                       new Action(() => {}));

BeginInvoke принудительно завершает все операции Dispatcher выше входного приоритета до продолжения текущего потока.

15.06.2010

2

Диспетчер работает в очереди. Так что может быть, что поток пользовательского интерфейса блокируется. Вы добавляете дополнительную работу в очередь через Dispatcher, но она никогда не будет выполнена, потому что поток пользовательского интерфейса блокируется.

Может быть, попробуйте это:

DispatcherFrame _frame = new DispatcherFrame();
Dispatcher.PushFrame(_frame);

Это поставит вашу работу перед работой, уже стоящей в очереди. Таким образом, поток пользовательского интерфейса выполнит работу, а затем снова заблокируется.

16.06.2010
Новые материалы

Объяснение документов 02: BERT
BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

Учебные заметки: создание моего первого пакета Node.js
Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


Для любых предложений по сайту: [email protected]