Windows Workflow Foundation с Windows Presentation Foundation - PullRequest
1 голос
/ 01 июля 2010

Я пытаюсь создать окно WPF в сервисе Workflow Com, но я получаю следующую ошибку:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: The calling thread must be STA, because many UI components require this.
   at System.Windows.Input.InputManager..ctor()
   at System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
   at System.Windows.Input.InputManager.get_Current()
   at System.Windows.Input.KeyboardNavigation..ctor()
   at System.Windows.FrameworkElement.FrameworkServices..ctor()
   at System.Windows.FrameworkElement.EnsureFrameworkServices()
   at System.Windows.FrameworkElement..ctor()
   at System.Windows.Controls.Control..ctor()
   at System.Windows.Window..ctor()
   at PACIExpress.SelectLanguage..ctor()

Кто-нибудь может мне помочь, пожалуйста?

Ответы [ 2 ]

2 голосов
/ 01 июля 2010

Ответ Киерена объясняет суть проблемы, а именно, что поток Workflow Foundation является потоком MTA, тогда как WPF требует потоков STA.Ответ Киерена не объясняет, как решить проблему.

Всякий раз, когда мне нужно получить доступ к содержимому WPF из потока MTA, я создаю поток STA, с помощью которого осуществляется доступ к содержимому.Для этого я использовал два решения, оба из которых работали хорошо:

Пулы STA в пуле

Когда объекты WPF не должны существовать после текущего вызова методаЯ использую класс STAThreadPool, который я написал.STAThreadPool реализует основные функции System.Threading.ThreadPool, но создает его потоки STA вместо MTA.Он также имеет метод RunOnSTAThread, который ставит в очередь пользовательский рабочий элемент, а затем ожидает завершения этого элемента.

Выделенные потоки STA

Это решение имеет больше накладных расходов, но требуетсялюбое время объекты WPF могут существовать для нескольких вызовов методов.Опять же, существует метод «RunOnSTAThread», который в этом случае реализуется с помощью:

  1. Если текущий поток STA, просто выполните действие
  2. Посмотрите в словаре, чтобы увидеть, еслисуществует поток STA для этого потока MTA (необходимо заблокировать словарь).
  3. Если поток STA не был найден: создайте поток STA и добавьте его в словарь.
  4. Сохраните действие вПоток STA, подайте сигнал на выполнение потока STA и дождитесь его завершения

Каждый поток STA выполняет цикл, который делает это:

  1. Если соответствующий поток MTA не являетсяжив, выход
  2. Дождитесь сигнала, что Действие готово к запуску, с тайм-аутом 10 секунд.Если тайм-аут, перейдите к шагу 1
  3. Выполнить действие
  4. Сигнал о завершении действия
  5. Перейти к шагу 1

Это решение на самом деле меньшекод, чем хорошо написанный STAThreadPool, но может быть менее эффективным, если есть много потоков.

2 голосов
/ 01 июля 2010

Исключение точно определяет проблему:

System.InvalidOperationException: вызывающим потоком должен быть STA, поскольку это требуется для многих компонентов пользовательского интерфейса.

Прежде всего, если«Служба Workflow Com» - это что-то вроде WCF или веб-службы, это не настольное приложение, которое может иметь пользовательский интерфейс.

В любом случае ваше приложение должно быть STA.

Разница междуMTA и STA:

Не могли бы вы объяснить STA и MTA?

Информация о WPF и STA: http://msdn.microsoft.com/en-gb/magazine/cc163328.aspx

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

http://blogs.msdn.com/b/jfoscoding/archive/2005/04/07/406341.aspx http://msdn.microsoft.com/en-us/library/system.stathreadattribute.aspx

Надеюсь, это поможет!

...