Вызывающий поток должен быть 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...
}
C ..
источник

Ответы:

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.

Timores
источник
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]атрибутом, и ошибка исчезнет! это магия :)

LIRON
источник
1

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

Райан Логгеритм
источник
-3

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

Балвант Рамани
источник
как писать объясните пожалуйста?
Тушар Гупта - curioustushar