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

Я использую 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...
}

person C..    schedule 24.02.2010    source источник


Ответы (9)


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

Application.Current.Dispatcher.Invoke((Action)delegate{
      // your code
});
person Amjad Abdelrahman    schedule 03.02.2014
comment
Ага, ребята, вы спасли мне жизнь !! - person Alex McManns; 30.03.2016
comment
Это настоящий ответ. Этим вы можете избавиться от глупости окон WPF. - person Andrew; 14.05.2016
comment
И аналогично этому, если вы используете MVVMLight, вы можете использовать DispatcherHelper.CheckBeginInvokeOnUI(Action action) - person TimothyP; 17.05.2016
comment
Эта задача казалась сложной и разочаровывающей, но этот снимок действительно классный! Большое спасибо ! - person Kay Lee; 28.09.2016
comment
Сработало у меня :) - person Naveen Kumar V; 05.06.2018
comment
@Andrew Это не глупость, вы просто пытаетесь получить доступ к потоку пользовательского интерфейса из фонового потока. - person Krusty; 24.01.2019
comment
Если у вас воспроизводится фоновый звук или идет анимация пользовательского интерфейса, будут ли потоки STA действительно мешать? Кажется странным, что OP хотел фоновый поток (по умолчанию MTA), но STA приемлем ... - person DAG; 29.04.2020
comment
Жирный голос за меня - person Dorin Baba; 09.01.2021

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

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

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

t.Start();

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

person Timores    schedule 24.02.2010
comment
Может ли это (с использованием STA) иметь побочные эффекты? - person Louis Rhys; 01.02.2012
comment
Основным побочным эффектом использования STA является то, что одновременные обратные вызовы COM сериализуются. Если вы не используете обратные вызовы COM, это не имеет значения. - person Timores; 02.02.2012
comment
Спас мою жизнь! Смог использовать это в приложении WPF, в котором размещен локальный API для интеграции между двумя разными приложениями! - person schizoid04; 07.10.2019

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

// 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();  
person Mohammad Atiour Islam    schedule 15.03.2016
comment
Спасибо. Это поможет при использовании класса Applicationcontext вместо Form. - person SaddamBinSyed; 23.10.2019
comment
Я открываю новую форму при нажатии кнопки, как и во многих других местах. Есть идеи, почему только одно из этих мест выдает эту ошибку? - person Paul McCarthy; 20.03.2020
comment
Спасибо, это сработало для моего конкретного случая использования! - person Neitherman; 03.09.2020

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

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

person Preet Sangha    schedule 24.02.2010
comment
Я попытался добавить его, как указано выше, но он все равно выдает ошибку: / - person C..; 25.02.2010
comment
Я не знаком с кодом. Можете ли вы отладить и точно определить строку кода, вызывающую это? - person Preet Sangha; 25.02.2010

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

Пример:

class Program {
    [STAThread]
    static void Main(string[] args) {
    // My code here
    }
}
person LiRoN    schedule 12.12.2018
comment
Я заметил, что использование тега [STAThread], похоже, не работает в асинхронном контексте, и что для меня имело значение, так это изменение вызывающего метода, чтобы он имел тег STAThread, а также не был асинхронным. - person Jack; 31.08.2020

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

person Ryan Loggerythm    schedule 20.11.2013

Если Application.Current имеет значение null, например, с помощью модульного теста, вы можете попробовать следующее:

 System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke( YOUR action )
person Ghislain Zabatio    schedule 08.01.2021

В моем случае я хотел запустить окно WPF из консольного приложения. Простая установка метода Main с [STAThread] не сработала.

Комбинация ответов Тимора и Мохаммеда сработала для меня:

private static void StaThreadWrapper(Action action)
{
    var t = new Thread(o =>
    {
        action();
        System.Windows.Threading.Dispatcher.Run();
    });
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
}

Пример использования:

StaThreadWrapper(() =>
{
    var mainWindow = new MainWindow();
    mainWindow.Show();
});
person datchung    schedule 21.06.2021

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

person Balvant Ramani    schedule 17.07.2013
comment
как писать, пожалуйста, объясните? - person Tushar Gupta - curioustushar; 17.07.2013