Измените элементы управления WPF из не основного streamа с помощью Dispatcher.Invoke

Я недавно начал программирование в WPF и столкнулся с следующей проблемой. Я не понимаю, как использовать метод Dispatcher.Invoke() . У меня есть опыт работы с streamами, и я сделал несколько простых программ Windows Forms, где я просто использовал

 Control.CheckForIllegalCrossThreadCalls = false; 

Да, я знаю, что это очень слабо, но это были простые приложения для мониторинга.

Фактически я делаю приложение WPF, которое извлекает данные в фоновом режиме, я начинаю новый stream, чтобы сделать вызов для извлечения данных (с веб-сервера), теперь я хочу отобразить его в моей форме WPF. Дело в том, что я не могу установить контроль над этим streamом. Даже ярлык или что-то еще. Как это можно решить?

Ответьте на комментарии:
@Jalfp:
Поэтому я использую этот метод Dispatcher в «новом проходе», когда получаю данные? Или я должен заставить фонового работника получить данные, поместить их в поле и запустить новый stream, который ждет, пока это поле будет заполнено, и вызовите диспетчера, чтобы отобразить полученные данные в элементах управления?

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

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

Если вам действительно нужно напрямую использовать диспетчер, это довольно просто:

 Application.Current.Dispatcher.BeginInvoke( DispatcherPriority.Background, new Action(() => this.progressBar.Value = 50)); 

japf ответил правильно. На всякий случай, если вы смотрите на многострочные действия, вы можете написать, как показано ниже.

 Application.Current.Dispatcher.BeginInvoke( DispatcherPriority.Background, new Action(() => { this.progressBar.Value = 50; })); 

Информация для других пользователей, которые хотят узнать о производительности:

Если ваш код НЕОБХОДИМО писать для высокой производительности, вы можете сначала проверить, требуется ли вызов с помощью флажка CheckAccess.

 if(Application.Current.Dispatcher.CheckAccess()) { this.progressBar.Value = 50; } else { Application.Current.Dispatcher.BeginInvoke( DispatcherPriority.Background, new Action(() => { this.progressBar.Value = 50; })); } 

Обратите внимание, что метод CheckAccess () скрыт от Visual Studio 2015, поэтому просто напишите его, не ожидая, что intellisense покажет его. Обратите внимание, что CheckAccess имеет накладные расходы на производительность (накладные расходы за несколько наносекунд). Это лучше, если вы хотите сохранить эту микросекунду, необходимую для выполнения «вызова» любой ценой. Кроме того, всегда существует возможность создать два метода (с вызовом и другими без) при вызове метода, если он находится в streamе пользовательского интерфейса или нет. Это редчайший случай, когда вы должны смотреть на этот аспект диспетчера.

  • понимание pthread_cond_wait () и pthread_cond_signal ()
  • Как прервать / отменить TPL Tasks?
  • Добавление элементов в массив Swift для нескольких streamов, вызывающих проблемы (поскольку массивы не являются streamобезопасными) - как мне обойти это?
  • Потоковое безопасное ленивое построение одноэлементного кода в C ++
  • Использование boost-streamа и нестатической функции classа
  • Почему большинство пользовательских интерфейсов однопоточных?
  • Более эффективный способ для цикла паузы
  • Каков правильный способ обработки событий на C ++?
  • Программа зависает, если stream создается в статическом блоке инициализатора
  • Как распространять исключения между streamами?
  • Насколько эффективна блокировка разблокированных мьютексов? Какова стоимость мьютекса?
  • Давайте будем гением компьютера.