Обеспечение, что вещи работают на потоке UI в WPF

Я создаю приложение WPF. Я делаю некоторую асинхронную связь со стороной сервера, и я использую агрегирование события с Призмой на клиенте. Обе этих вещи приводят к новым потокам, которые будут порождены, которые не являются потоком UI. Если я попытаюсь сделать "операции WPF" на них обработчик обратного вызова и потоки обработчика событий, то мир развалится, который он теперь начал делать.

Сначала я встретил проблемы, пытающиеся создать некоторые объекты WPF в обратном вызове с сервера. Мне сказали, что поток должен был работать в режиме STA. Теперь я пытаюсь обновить некоторые данные UI в обработчике событий Призмы, и мне говорят что:

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

Так; что ключ к разбиранию в вещах в WPF? Я читал на Диспетчере WPF в этом сообщении MSDN. Я начинаю получать его, но я еще не мастер.

  1. Ключ, чтобы всегда использовать Диспетчера. Вызовите, когда я должен выполнить что-то, что я не уверен, будет назван на потоке UI?
  2. Имеет значение, если это на самом деле назвали на потоке UI, и я делаю Диспетчера. Вызвать так или иначе?
  3. Диспетчер. Вызовите = синхронно. Dispathcher. BeginInvoke = асинхронный?
  4. Будет Диспетчер. Вызовите запрашивают поток UI и затем останавливаются для ожидания его? Это - плохая практика и риск меньшего количества быстро реагирующих программ?
  5. Как я получаю диспетчера так или иначе? Будет Диспетчер. CurrentDispatcher всегда дают мне диспетчера, представляющего поток UI?
  6. Там будет существовать больше чем один Диспетчер, или "Диспетчер" является в основном тем же как потоком UI для приложения?
  7. И каково соглашение с BackgroundWorker? Когда я использую это вместо этого? Я предполагаю, что это всегда асинхронно?
  8. Будет все, что работает на потоке UI (будучи Вызванным) быть выполненным в режиме квартиры STA? Т.е. если у меня будет что-то, что требует, чтобы быть выполненным в режиме STA - то будет Диспетчер. Вызвать быть достаточными?

Кто-либо хочет clearify вещи для меня? Какие-либо связанные рекомендации, и т.д.? Спасибо!

36
задан tehDorf 9 October 2012 в 23:33
поделиться

1 ответ

Рассматривая каждый из ваших вопросов один за другим:

  1. Не совсем; вы должны вызывать поток пользовательского интерфейса только при необходимости. См. №2.
  2. Да, это важно. Вы не должны просто автоматически вызывать все. Ключ заключается в том, чтобы вызывать поток пользовательского интерфейса только в случае необходимости. Для этого можно использовать метод Dispatcher.CheckAccess .
  3. Это верно.
  4. Также правильно, и да, вы рискуете получить менее отзывчивые программы. В большинстве случаев вы не столкнетесь с серьезным падением производительности (мы говорим о миллисекундах для переключения контекста), но вы должны только Invoke , если это необходимо. При этом в некоторых случаях это неизбежно, поэтому нет, я бы вообще не сказал, что это плохая практика. Это всего лишь одно решение проблемы, с которой вы время от времени будете сталкиваться.
  5. Во всех случаях, которые я видел, я полагался на Dispatcher.CurrentDispatcher . Для сложных сценариев этого может быть недостаточно, но я (лично) их не видел.
  6. Не совсем правильно, но такой образ мышления не принесет никакого вреда. Скажу так: диспетчер может использоваться для получения доступа к потоку пользовательского интерфейса приложения. Но сам по себе он не является потоком пользовательского интерфейса.
  7. BackgroundWorker обычно используется, когда у вас трудоемкая операция и вы хотите сохранить отзывчивый пользовательский интерфейс при выполнении этой операции в фоновом режиме. Обычно вы не используете BackgroundWorker вместо Invoke, скорее вы используете BackgroundWorker вместе с Invoke.То есть, если вам нужно обновить какой-либо объект пользовательского интерфейса в вашем BackgroundWorker, вы можете вызвать поток пользовательского интерфейса, выполнить обновление, а затем вернуться к исходной операции.
  8. Да. Поток пользовательского интерфейса приложения WPF по определению должен выполняться в однопоточном подразделении.

О BackgroundWorker можно много сказать, я уверен, что ему уже посвящено много вопросов, поэтому я не буду вдаваться в подробности. Если вам интересно, посетите страницу MSDN для класса BackgroundWorker .

37
ответ дан 27 November 2019 в 06:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: