«Вызывающий поток должен быть STA, потому что многие компоненты пользовательского интерфейса требуют этого» ошибка при создании всплывающего окна WPF в потоке - PullRequest
14 голосов
/ 17 апреля 2010

У меня есть приложение WPF, в котором поток проверяет какое-то значение. В некоторых случаях я показываю всплывающее окно Window для отображения сообщения. Когда я создаю это всплывающее окно в потоке, конструктор всплывающего окна создает исключение:

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

Как мне устранить эту ошибку?

Это мой код для создания всплывающего окна:

// using System.Threading;
// using System.Windows.Threading;
Thread Messagethread = new Thread(new ThreadStart(delegate()
{
    DispatcherOperation DispacherOP = 
        frmMassenger.Dispatcher.BeginInvoke(
            DispatcherPriority.Normal,
            new Action(delegate()
            {
                frmMassenger.Show();
            }));
}));
Messagethread.Start();

Ответы [ 2 ]

14 голосов
/ 17 апреля 2010

Для потока, в котором вы пытаетесь запустить элемент GUI, вам нужно установить состояние квартиры потока на STA ДО , когда вы его запустите.

Пример:

myThread.SetApartmentState(ApartmentState.STA);
myThread.Start();
9 голосов
/ 14 июля 2010

Абсолютно Dispatcher - это единственный способ сделать что-то (в определенной теме), когда мы работаем с многопоточностью в WPF!

Но для работы с Dispatcher необходимо знать 2 вещи:

  1. Слишком много способов использовать Dispatcher, например Dispatcher_Operation, [window.dispatcher] или т. д.
  2. Мы должны call dispatcher in the main thread of app (эта нить должна быть нитью STA)

Так например: если мы хотим показать другое окно [wpf] в другом потоке, мы можем использовать этот код:

Frmexample frmexample = new Frmexample();
            Frmexample .Dispatcher.BeginInvoke
                (System.Windows.Threading.DispatcherPriority.Normal,
                (Action)(() =>
                {
                    frmexample.Show();
                    //---or do any thing you want with that form
                }
                ));

Подсказка: Remember - we can't access any fields or properties from out dispatcher, so use that wisely

...