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.