Le thread appelant doit être STA, car de nombreux composants de l'interface utilisateur l'exigent

174

J'utilise http://www.codeproject.com/KB/IP/Facebook_API.aspx

J'essaie d'appeler le XAML qui est créé à l'aide de WPF . Mais cela me donne une erreur:

Le thread appelant doit être STA, car de nombreux composants d'interface utilisateur l'exigent.

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

FacebookApplication.FacebookFriendsList ffl = new FacebookFriendsList();

Mais cela me donne cette erreur.

J'ai ajouté un travailleur d'arrière-plan:

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...
}
C ..
la source

Réponses:

223

Essayez d'appeler votre code depuis le répartiteur :

Application.Current.Dispatcher.Invoke((Action)delegate{
      // your code
});
Amjad Abdelrahman
la source
Ouais, vous avez sauvé ma vie !!
Alex McManns
11
C'est la vraie réponse. Vous pouvez pirater la stupidité de la fenêtre de WPF avec cela.
Andrew
7
Et de la même façon, si vous utilisez MVVMLight, vous pouvez l'utiliserDispatcherHelper.CheckBeginInvokeOnUI(Action action)
TimothyP
Ce problème m'a paru compliqué & frustré mais ce cliché est vraiment cool! Merci beaucoup !
Kay Lee
4
@Andrew Ce n'est pas de la stupidité, vous essayez simplement d'accéder au fil de l'interface utilisateur à partir d'un fil d'arrière-plan.
Krusty
139

Si vous effectuez l'appel à partir du 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 se trouver dans un STA (cloisonnement monothread), ce qui n'est pas le cas pour les threads de travail en arrière-plan. Vous devez créer le fil vous-même, comme ceci:

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

t.Start();

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

Timores
la source
2
cela (en utilisant STA) peut-il avoir des effets secondaires?
Louis Rhys
10
Le principal effet secondaire d'être STA est que les rappels COM simultanés sont sérialisés. Si vous n'utilisez pas de rappels COM, cela ne devrait pas avoir d'importance.
Timores
Sauvé ma vie! A pu l'utiliser dans une application WPF qui hébergeait une API locale pour une intégration entre deux applications différentes!
schizoid04
18

Vous pouvez également essayer ceci

// 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();  
atik sarker
la source
Merci. Cela vous aidera lors de l'utilisation de la classe Applicationcontext au lieu de Form.
SaddamBinSyed
J'ouvre un nouveau formulaire lorsqu'un bouton est cliqué comme je le fais dans de nombreux autres endroits. Une idée pourquoi un seul de ces endroits lance cette erreur?
Paul McCarthy
17

Je soupçonne que vous recevez un rappel vers un composant d'interface utilisateur à partir d'un thread d'arrière-plan. Je vous recommande de passer cet appel à l'aide d'un BackgroundWorker car il est compatible avec les threads d'interface utilisateur.

Pour BackgroundWorker, le programme principal doit être marqué comme [STAThread].

Preet Sangha
la source
1
J'ai essayé de l'ajouter, comme ci-dessus, mais cela me donne toujours l'erreur: /
C ..
Je ne suis pas familier avec le code. Pouvez-vous déboguer et découvrir exactement la ligne de code à l'origine de cela?
Preet Sangha
3

Marquez simplement votre programme avec l' [STAThread]attribut et l'erreur disparaît! c'est magique :)

LiRoN
la source
1

Pour moi, cette erreur s'est produite en raison de la transmission d'un paramètre nul. La vérification des valeurs des variables a résolu mon problème sans avoir à changer le code. J'ai utilisé BackgroundWorker.

Ryan Loggerythm
la source
-3

Si vous appelez une nouvelle instruction d'interface utilisateur de fenêtre dans un thread existant, cela génère une erreur. Au lieu de cela, créez un nouveau thread à l'intérieur du thread principal et écrivez l'instruction de l'interface utilisateur de la fenêtre dans le nouveau thread enfant.

Balvant Ramani
la source
comment écrire pls expliquer?
Tushar Gupta - curioustushar