O encadeamento de chamada deve ser STA, porque muitos componentes da interface do usuário exigem isso


174

Estou usando http://www.codeproject.com/KB/IP/Facebook_API.aspx

Estou tentando chamar o XAML que é criado usando o WPF . Mas isso me dá um erro:

O segmento de chamada deve ser STA, porque muitos componentes da interface do usuário exigem isso.

Não sei o que fazer Estou tentando fazer isso:

FacebookApplication.FacebookFriendsList ffl = new FacebookFriendsList();

Mas está me dando esse erro.

Eu adicionei um trabalhador em segundo plano:

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

Respostas:


222

Tente chamar seu código do expedidor :

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

Yeahhh, vocês salvaram minha vida !!
Alex McManns

11
Esta é a verdadeira resposta. Você pode cortar a estupidez da janela do WPF com isso.
Andrew

7
E semelhante a isso, se você estiver usando o MVVMLight, você pode usarDispatcherHelper.CheckBeginInvokeOnUI(Action action)
TimothyP 17/16/16

Esse problema parecia complicado e frustrado, mas essa foto é muito legal! Muito obrigado !
Kay Lee

4
@ Andrew Não é estupidez, você está simplesmente tentando acessar o thread da interface do usuário a partir de um thread em segundo plano.
Krusty

139

Se você fizer a chamada a partir do encadeamento principal, deverá adicionar o atributo STAThread ao método Main, conforme indicado na resposta anterior.

Se você usar um encadeamento separado, ele precisará estar em um STA (apartamento de encadeamento único), o que não é o caso dos encadeamentos de trabalho em segundo plano. Você mesmo deve criar o thread, assim:

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

t.Start();

com ThreadProc sendo um delegado do tipo ThreadStart.


2
isso (usando STA) possível pode ter efeito colateral?
Louis Rhys

10
O principal efeito colateral de ser STA é que os retornos de chamada COM simultâneos são serializados. Se você não estiver usando retornos de chamada COM, isso não deve importar.
Timores 02/02/12

Salvou a minha vida! Conseguiu usar isso em um aplicativo WPF que hospedava uma API local para uma integração entre dois aplicativos diferentes!
precisa

18

Você também pode tentar isso

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

Obrigado. Isso ajudará ao usar a classe Applicationcontext em vez de Form.
SaddamBinSyed 23/10/19

Estou abrindo um novo formulário quando um botão é clicado, como faço em vários outros lugares. Alguma idéia de por que apenas um desses lugares está lançando esse erro?
Paul McCarthy

17

Eu suspeito que você esteja recebendo um retorno de chamada para um componente de interface do usuário a partir de um thread em segundo plano. Eu recomendo que você faça essa chamada usando um BackgroundWorker, pois isso reconhece o thread da interface do usuário.

Para o BackgroundWorker, o programa principal deve ser marcado como [STAThread].


1
Tentei adicioná-lo, como acima, mas ele ainda me dá o erro: /
C ..

Eu não sou familiar com o código. Você pode depurar e descobrir exatamente a linha de código que está causando isso?
Preet Sangha

3

Basta marcar o seu programa com o [STAThread]atributo e o erro desaparece! é Magica :)


1

Para mim, esse erro ocorreu devido à passagem de um parâmetro nulo. A verificação dos valores das variáveis ​​corrigiu meu problema sem precisar alterar o código. Eu usei o BackgroundWorker.


-3

Se você chamar uma nova instrução de interface do usuário da janela em um encadeamento existente, ele emitirá um erro. Em vez disso, crie um novo thread dentro do thread principal e escreva a instrução da interface do usuário da janela no novo thread filho.


como escrever pls explicar?
Tushar Gupta - curioustushar
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.