Обеспечение того, чтобы все выполнялось в streamе пользовательского интерфейса в WPF

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

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

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

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

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

Кто-нибудь хочет уточнить для меня вещи? Любые соответствующие рекомендации и т. Д.? Благодаря!

Переходя по каждому из ваших вопросов, один за другим:

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

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

  • В каких сценариях замораживание объектов WPF значительно повышает производительность?
  • Имя не существует в ошибке пространства имен в XAML
  • Стиль windows WPF MessageBox
  • Копирование из и в буфер обмена теряет прозрачность изображения
  • WPF: автозаполнение TextBox, ... снова
  • WPF MVVM: Конвенция о конфигурации для ResourceDictionary?
  • Ошибка ReSharper WPF: «Не удается разрешить символ« MyVariable »из-за неизвестного DataContext»
  • Что такое имена столбцов DataTable с точками, что делает их непригодными для управления DataGrid WPF?
  • KeyBinding в UserControl не работает, когда TextBox имеет фокус
  • Как сортировать наблюдаемую коллекцию?
  • Как обнаружить сломанные привязки данных WPF?
  • Давайте будем гением компьютера.