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.