多くのUIコンポーネントがこれを必要とするため、呼び出しスレッドはSTAである必要があります


174

私はhttp://www.codeproject.com/KB/IP/Facebook_API.aspxを使用しています

WPFを使用して作成されたXAMLを呼び出そうとしています。しかし、それは私にエラーを与えます:

多くのUIコンポーネントがSTAを必要とするため、呼び出しスレッドは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
});

うん、あなたたちは私の命を救った!
Alex McManns

11
これが本当の答えです。これで、WPFのウィンドウの愚かさをハッキングできます。
Andrew

7
これと同様に、MVVMLightを使用している場合は、使用できますDispatcherHelper.CheckBeginInvokeOnUI(Action action)
TimothyP

この問題は複雑でイライラしているように見えましたが、このショットは本当にクールです!どうもありがとうございます !
Kay Lee

4
@Andrew愚かではなく、単にバックグラウンドスレッドからUIスレッドにアクセスしようとしているだけです。
Krusty

139

前の回答で述べたように、メインスレッドから呼び出しを行う場合は、STAThread属性をMainメソッドに追加する必要があります。

別のスレッドを使用する場合は、バックグラウンドワーカースレッドの場合とは異なり、STA(シングルスレッドアパートメント)にある必要があります。次のように、自分でスレッドを作成する必要があります。

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

t.Start();

ThreadProcはThreadStartタイプのデリゲートです。


2
これは(STAを使用して)副作用があるのでしょうか?
Louis Rhys、2012

10
STAであることの主な副作用は、同時COMコールバックがシリアル化されることです。COMコールバックを使用していない場合、問題はありません。
Timores、

私を助けた!2つの異なるアプリ間の統合のためにローカルAPIをホストするWPFアプリでこれを使用できました!
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();  

ありがとう。これは、Formの代わりにApplicationcontextクラスを使用するときに役立ちます。
SaddamBinSyed

他の多くの場所と同じように、ボタンをクリックすると新しいフォームが開きます。なぜこれらの場所の1つだけがこのエラーをスローしているのでしょうか?
ポールマッカーシー

17

バックグラウンドスレッドからUIコンポーネントへのコールバックを取得していると思います。UIスレッドを認識するため、BackgroundWorkerを使用して呼び出しを行うことをお勧めします。

BackgroundWorkerの場合、メインプログラムは[STAThread]としてマークされている必要があります。


1
上記のように追加しようとしましたが、それでもエラーが表示されます:/
C ..

私はコードに精通していません。これを引き起こしているコード行をデバッグして正確に見つけることができますか?
Preet Sangha

3

[STAThread]属性にプログラムをマークするだけでエラーはなくなります!魔法です :)


1

私にとって、このエラーはnullパラメータが渡されたために発生しました。変数の値を確認すると、コードを変更せずに問題が解決しました。私はBackgroundWorkerを使用しました。


-3

既存のスレッドで新しいウィンドウUIステートメントを呼び出すと、エラーがスローされます。その代わりに、メインスレッド内に新しいスレッドを作成し、新しい子スレッドにウィンドウUIステートメントを記述します。


plsの説明を書く方法は?
Tushar Gupta-curioustushar 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.