2010-02-24 4 views
109

J'utilise http://www.codeproject.com/KB/IP/Facebook_API.aspxLe thread appelant doit être STA, parce que de nombreux composants de l'interface utilisateur ont besoin de ce

Je suis en train d'appeler la XAML qui est créé à l'aide WPF. Mais il me donne une erreur:

The calling thread must be STA, because many UI components require this.

Je ne sais pas quoi faire. J'essaye de faire ceci:

FacebookApplication.FacebookFriendsList ffl = new FacebookFriendsList(); 

Mais c'est me donner cette erreur.

J'ai ajouté un travailleur de fond:

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

Répondre

15

Je soupçonne que vous obtenez un rappel à un composant d'interface utilisateur à partir d'un fil d'arrière-plan. Je vous recommande de faire cet appel à l'aide d'un BackgroundWorker car il s'agit d'un thread sensible à l'interface utilisateur. Pour le BackgroundWorker, le programme principal doit être marqué comme [STAThread].

+0

J'ai essayé d'ajouter, comme ci-dessus, mais il me donne toujours l'erreur:/ –

+0

Je ne suis pas familliar avec le code. Pouvez-vous déboguer et trouver exactement la ligne de code causant cela? –

121

Si vous appelez depuis le thread principal, vous devez ajouter l'attribut STAThread à la méthode Main, comme indiqué dans la réponse précédente.

Si vous utilisez un thread séparé, il doit être dans un STA (single-threaded apartment), ce qui n'est pas le cas pour les threads de travail en arrière-plan. Vous devez créer le fil vous, comme ceci:

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

t.Start(); 

avec ThreadProc étant un délégué de type ThreadStart.

+2

cela (en utilisant STA) peut-il avoir un effet secondaire? –

+9

L'effet secondaire principal de STA est que les rappels COM simultanés sont sérialisés. Si vous n'utilisez pas les rappels COM, cela ne devrait pas avoir d'importance. – Timores

-2

Si vous appelez une nouvelle déclaration d'interface utilisateur dans un thread existant, une erreur se produit. Au lieu de cela, créez un nouveau thread dans le thread principal et écrivez l'instruction UI de la fenêtre dans le nouveau thread enfant.

+0

comment écrire pls expliquer? –

0

Pour moi, cette erreur est survenue en raison de la transmission d'un paramètre null. La vérification des valeurs de variables a corrigé mon problème sans avoir à modifier le code. J'ai utilisé BackgroundWorker.

119

Essayez d'appeler votre code de la dispatcher:

Application.Current.Dispatcher.Invoke((Action)delegate{ 

//your code 

}); 
+0

Yeahhh, vous m'avez sauvé la vie !! –

+6

Ceci est la réponse * réelle *. Vous pouvez pirater la stupidité de la fenêtre de WPF avec ceci. – Andrew

+5

Et similaire à cela, si vous utilisez MVVMLight, vous pouvez utiliser 'DispatcherHelper.CheckBeginInvokeOnUI (Action) – TimothyP

4

Vous pouvez également essayer

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

Un nouveau thread n'est pas nécessaire, appelez simplement le thread UI. – rolls

3

Application.Current.Dispatcher.Invoke ((Action) délégué {// mettre le code ici });

+0

Ceci est la même que cette réponse: https://stackoverflow.com/a/21539361/732673 –

Questions connexes