Ответ Киерена объясняет суть проблемы, а именно, что поток Workflow Foundation является потоком MTA, тогда как WPF требует потоков STA.Ответ Киерена не объясняет, как решить проблему.
Всякий раз, когда мне нужно получить доступ к содержимому WPF из потока MTA, я создаю поток STA, с помощью которого осуществляется доступ к содержимому.Для этого я использовал два решения, оба из которых работали хорошо:
Пулы STA в пуле
Когда объекты WPF не должны существовать после текущего вызова методаЯ использую класс STAThreadPool, который я написал.STAThreadPool реализует основные функции System.Threading.ThreadPool, но создает его потоки STA вместо MTA.Он также имеет метод RunOnSTAThread, который ставит в очередь пользовательский рабочий элемент, а затем ожидает завершения этого элемента.
Выделенные потоки STA
Это решение имеет больше накладных расходов, но требуетсялюбое время объекты WPF могут существовать для нескольких вызовов методов.Опять же, существует метод «RunOnSTAThread», который в этом случае реализуется с помощью:
- Если текущий поток STA, просто выполните действие
- Посмотрите в словаре, чтобы увидеть, еслисуществует поток STA для этого потока MTA (необходимо заблокировать словарь).
- Если поток STA не был найден: создайте поток STA и добавьте его в словарь.
- Сохраните действие вПоток STA, подайте сигнал на выполнение потока STA и дождитесь его завершения
Каждый поток STA выполняет цикл, который делает это:
- Если соответствующий поток MTA не являетсяжив, выход
- Дождитесь сигнала, что Действие готово к запуску, с тайм-аутом 10 секунд.Если тайм-аут, перейдите к шагу 1
- Выполнить действие
- Сигнал о завершении действия
- Перейти к шагу 1
Это решение на самом деле меньшекод, чем хорошо написанный STAThreadPool, но может быть менее эффективным, если есть много потоков.