Подтвердить что ты не робот

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

У меня есть приложение 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();
4b9b3361

Ответ 1

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

Но для работы с Диспетчером мы должны знать 2 вещи:

  • Слишком много способов использования диспетчера, например Dispatcher_Operation, [window.dispatcher] и т.д.
  • Мы должны 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

Ответ 2

Для вашего потока, в который вы пытаетесь запустить элемент GUI, вам нужно установить состояние вашего потока в STA ПЕРЕД, чтобы запустить его.

Пример:

myThread.SetApartmentState(ApartmentState.STA);
myThread.Start();