Wątkiem wywołującym musi być STA, ponieważ wymaga tego wiele składników interfejsu użytkownika


174

Używam http://www.codeproject.com/KB/IP/Facebook_API.aspx

Próbuję wywołać XAML, który jest tworzony przy użyciu WPF . Ale daje mi błąd:

Wątkiem wywołującym musi być STA, ponieważ wymaga tego wiele składników interfejsu użytkownika.

Nie wiem co mam robić. Próbuję to zrobić:

FacebookApplication.FacebookFriendsList ffl = new FacebookFriendsList();

Ale to daje mi ten błąd.

Dodałem pracownika w tle:

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

Odpowiedzi:


222

Spróbuj wywołać swój kod z dyspozytora :

Application.Current.Dispatcher.Invoke((Action)delegate{
      // your code
});

Yeahhh, uratowaliście mi życie !!
Alex McManns

11
To jest prawdziwa odpowiedź. Dzięki temu możesz odhakować głupotę okien WPF.
Andrew,

7
I podobnie do tego, jeśli używasz MVVMLight, możesz użyćDispatcherHelper.CheckBeginInvokeOnUI(Action action)
TimothyP

Ten problem wydawał się skomplikowany i sfrustrowany, ale to ujęcie jest naprawdę fajne! Dziękuję bardzo !
Kay Lee

4
@Andrew To nie jest głupota, po prostu próbujesz uzyskać dostęp do wątku interfejsu użytkownika z wątku w tle.
Krusty

139

Jeśli wykonujesz wywołanie z głównego wątku, musisz dodać atrybut STAThread do metody Main, jak stwierdzono w poprzedniej odpowiedzi.

Jeśli używasz oddzielnego wątku, musi on znajdować się w STA (mieszkaniu jednowątkowym), co nie ma miejsca w przypadku wątków roboczych w tle. Musisz sam stworzyć wątek, w ten sposób:

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

t.Start();

z ThreadProc będącym delegatem typu ThreadStart.


2
czy to (używając STA) może mieć efekt uboczny?
Louis Rhys

10
Głównym efektem ubocznym bycia STA jest to, że jednoczesne wywołania zwrotne COM są serializowane. Jeśli nie używasz wywołań zwrotnych COM, nie powinno to mieć znaczenia.
Timores

Uratował mi życie! Był w stanie użyć tego w aplikacji WPF, która hostowała lokalny interfejs API do integracji między dwiema różnymi aplikacjami!
schizoid04

18

Możesz także spróbować tego

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

Dzięki. Pomoże to w przypadku używania klasy Applicationcontext zamiast Form.
SaddamBinSyed

Otwieram nowy formularz po kliknięciu przycisku, tak jak robię to w wielu innych miejscach. Masz jakiś pomysł, dlaczego tylko jedno z tych miejsc rzuca ten błąd?
Paul McCarthy

17

Podejrzewam, że otrzymujesz wywołanie zwrotne do składnika interfejsu użytkownika z wątku w tle. Zalecam wykonanie tego wywołania przy użyciu BackgroundWorker, ponieważ jest to świadomy wątek interfejsu użytkownika.

W przypadku BackgroundWorker główny program powinien być oznaczony jako [STAThread].


1
Próbowałem go dodać jak wyżej, ale nadal daje mi błąd: /
C ..

Nie znam kodu. Czy możesz przeprowadzić debugowanie i znaleźć dokładną linię kodu, która to powoduje?
Preet Sangha

3

Po prostu oznacz swój program [STAThread]atrybutem, a błąd zniknie! to magia :)


1

U mnie ten błąd wystąpił z powodu przekazania parametru o wartości null. Sprawdzanie wartości zmiennych rozwiązało mój problem bez konieczności zmiany kodu. Użyłem BackgroundWorker.


-3

Jeśli wywołasz instrukcję interfejsu użytkownika nowego okna w istniejącym wątku, zgłosi błąd. Zamiast tego utwórz nowy wątek w głównym wątku i napisz instrukcję interfejsu użytkownika okna w nowym wątku podrzędnym.


jak napisać pls wyjaśnić?
Tushar Gupta - curioustushar
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.