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


174

Я использую http://www.codeproject.com/KB/IP/Facebook_API.aspx

Я пытаюсь вызвать XAML, созданный с использованием WPF . Но это дает мне ошибку:

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

Я не знаю что делать Я пытаюсь сделать это:

FacebookApplication.FacebookFriendsList ffl = new FacebookFriendsList();

Но это дает мне эту ошибку.

Я добавил фоновый рабочий:

static BackgroundWorker bw = new BackgroundWorker();

static void Main(string[] args)
{
    bw.DoWork += bw_DoWork;
    bw.RunWorkerAsync("Message to worker");
    Console.ReadLine();
}

static void bw_DoWork(object sender, DoWorkEventArgs e)
{
    // This is called on the worker thread
    FacebookApplication.FacebookFriendsList ffl = new FacebookFriendsList();

    Console.WriteLine(e.Argument);        // Writes "Message to worker"

    // Perform time-consuming task...
}

Ответы:


223

Попробуйте вызвать ваш код у диспетчера :

Application.Current.Dispatcher.Invoke((Action)delegate{
      // your code
});

Да, вы, ребята, спасли мне жизнь !!
— Алекс Макманнс

11
Это настоящий ответ. С этим можно покончить с глупостью окна WPF.
— Андрей

7
И аналогично этому, если вы используете MVVMLight, вы можете использоватьDispatcherHelper.CheckBeginInvokeOnUI(Action action)
— TimothyP

Эта проблема казалась сложной и разочарованной, но этот снимок действительно крутой! Спасибо вам большое !
— Кей Ли,

4
@Andrew Это не глупость, вы просто пытаетесь получить доступ к потоку пользовательского интерфейса из фонового потока.
— Красти

139

Если вы делаете вызов из основного потока, вы должны добавить атрибут STAThread в метод Main, как указано в предыдущем ответе.

Если вы используете отдельный поток, он должен находиться в STA (однопотоковой квартире), что не относится к фоновым рабочим потокам. Вы должны создать тему самостоятельно, например так:

Thread t = new Thread(ThreadProc);
t.SetApartmentState(ApartmentState.STA);

t.Start();

с ThreadProc, являющимся делегатом типа ThreadStart.


2
может ли это (при использовании STA) иметь побочный эффект?
— Луи Рис

10
Основным побочным эффектом STA является то, что одновременные обратные вызовы COM сериализуются. Если вы не используете обратные вызовы COM, это не должно иметь значения.
— Тимор

Спас мою жизнь! Был в состоянии использовать это в приложении WPF, которое размещало локальный API для интеграции между двумя различными приложениями!
— schizoid04

18

Вы также можете попробовать это

// create a thread  
Thread newWindowThread = new Thread(new ThreadStart(() =>  
{  
    // create and show the window
    FaxImageLoad obj = new FaxImageLoad(destination);  
    obj.Show();  

    // start the Dispatcher processing  
    System.Windows.Threading.Dispatcher.Run();  
}));  

// set the apartment state  
newWindowThread.SetApartmentState(ApartmentState.STA);  

// make the thread a background thread  
newWindowThread.IsBackground = true;  

// start the thread  
newWindowThread.Start();  

Спасибо. Это поможет при использовании класса Applicationcontext вместо Form.
— SaddamBinSyed

Я открываю новую форму при нажатии кнопки, как и во многих других местах. Есть идеи, почему только одно из этих мест выдает эту ошибку?
— Пол Маккарти

17

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

Для BackgroundWorker основная программа должна быть помечена как [STAThread].


1
Я попытался добавить его, как указано выше, но все равно выдает ошибку: /
— C ..

Я не знаком с кодом. Можете ли вы отладить и выяснить, какая именно строка кода вызывает это?
— Прит Сангха

3

Просто пометьте вашу программу [STAThread]атрибутом, и ошибка исчезнет! это магия :)


1

Для меня эта ошибка произошла из-за передачи нулевого параметра. Проверка значений переменных устранила мою проблему без необходимости изменения кода. Я использовал BackgroundWorker.


-3

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


как писать объясните пожалуйста?
— Тушар Гупта - curioustushar
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.