Викликає потік повинен бути 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...
}

Відповіді:


222

Спробуйте викликати свій код у диспетчера :

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

Якщо ви викликаєте новий оператор інтерфейсу вікна в існуючому потоці, він видає помилку. Замість цього створіть новий потік всередині основного потоку та напишіть у новому дочірньому потоці операційний інтерфейс вікна.


як написати pls пояснити?
Тушар Гупта - curioustushar
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.