调用线程必须是STA,因为许多UI组件都需要这个

时间:2010-02-24 22:06:34

标签: wpf xaml multithreading facebook

我正在使用http://www.codeproject.com/KB/IP/Facebook_API.aspx

我正在尝试使用XAML调用WPF。但它给了我一个错误:

  

调用线程必须是STA,因为许多UI组件都需要这个。

我不知道该怎么办。我想这样做:

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...
}

9 个答案:

答案 0 :(得分:176)

尝试从dispatcher

调用您的代码
Application.Current.Dispatcher.Invoke((Action)delegate{
      // your code
});

答案 1 :(得分:129)

如果从主线程进行调用,则必须将STAThread属性添加到Main方法,如上一个答案中所述。

如果使用单独的线程,则需要在STA(单线程单元)中,而后台工作线程不是这种情况。你必须自己创建线程,如下所示:

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

t.Start();

ThreadProc是ThreadStart类型的委托。

答案 2 :(得分:15)

我怀疑你是从后台线程获得UI组件的回调。我建议您使用BackgroundWorker进行该调用,因为这是UI线程识别。

对于BackgroundWorker,主程序应标记为[STAThread]。

答案 3 :(得分:11)

你也可以尝试这个

// 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();  

答案 4 :(得分:1)

只需使用[STAThread]属性标记您的程序,错误就会消失!太神奇了:)

答案 5 :(得分:1)

如果 Application.Currentnull,例如通过单元测试,你可以试试这个:

 System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke( YOUR action )

答案 6 :(得分:0)

对我来说,发生此错误是因为传递了null参数。检查变量值可以解决我的问题,而无需更改代码。我使用了BackgroundWorker。

答案 7 :(得分:0)

就我而言,我想从控制台应用程序启动 WPF 窗口。简单地使用 [STAThread] 设置 Main 方法是行不通的。

Timores 和 Mohammad 的回答对我有用:

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();
});

答案 8 :(得分:-3)

如果在现有线程中调用新窗口UI语句,则会引发错误。而不是在主线程内创建一个新线程,并在新的子线程中编写窗口UI语句。