Pergunta

Basta saber qual a diferença entre BeginInvoke() e Invoke() são?

Principalmente o que cada um poderia ser utilizado.

EDIT: Qual é a diferença entre a criação de um objeto de segmentação e chamando invoco sobre isso e apenas chamando BeginInvoke() em um delegado? ou são a mesma coisa?

Foi útil?

Solução

Você quer dizer Delegate.Invoke / BeginInvoke ou Control.Invoke / BeginInvoke?

  • Delegate.Invoke:. Executa de forma síncrona, no mesmo segmento
  • Delegate.BeginInvoke:. Executado de forma assíncrona, em um segmento pool de threads
  • Control.Invoke:. Executado no segmento interface do usuário, mas chamando thread espera para a conclusão antes de continuar
  • Control.BeginInvoke:. Executado no segmento interface do usuário, e chamando thread não aguardar a conclusão

A resposta de Tim menciona quando você pode querer usar BeginInvoke -. Embora a maioria era voltada para Delegate.BeginInvoke, suspeito

para Windows Forms aplicativos, gostaria de sugerir que você deve normalmente usar BeginInvoke. Dessa forma, você não precisa se preocupar com impasse, por exemplo - mas você precisa entender que a interface do usuário não pode ter sido atualizado pelo tempo que você próxima olhar para ele! Em particular, você não deve modificar dados que o segmento interface do usuário pode estar prestes a usar para fins de exibição. Por exemplo, se você tem uma pessoa com propriedades nome e sobrenome, e você fez:

person.FirstName = "Kevin"; // person is a shared reference
person.LastName = "Spacey";
control.BeginInvoke(UpdateName);
person.FirstName = "Keyser";
person.LastName = "Soze";

, em seguida, a interface do usuário pode muito bem acabar exibindo "Keyser Spacey". (Há uma chance fora que poderia exibir "Kevin Soze", mas apenas através da estranheza do modelo de memória.)

A menos que você tem esse tipo de problema, no entanto, Control.BeginInvoke é mais fácil de acertar, e evitar a sua discussão de fundo de ter que esperar por nenhuma boa razão. Note-se que a equipe de Windows Forms tem garantido que você pode usar Control.BeginInvoke em um "dispare e esqueça" forma - ou seja, sem nunca chamar EndInvoke. Isso não é verdade de chamadas assíncronas em geral:. Normalmente cada BeginXXX deve ter uma chamada EndXXX correspondente, geralmente no retorno de chamada

Outras dicas

Com base na resposta de Jon Skeet, há momentos em que você deseja chamar um delegado e espera para a sua execução seja concluído antes de o segmento atual continua. Nesses casos, a chamada Invoke é o que você quer.

Em aplicações multi-threading, você pode não querer um fio de esperar em um delegado para a execução de chegada, especialmente se que executa delegado I / O (o que poderia tornar o delegado e seu bloco de rosca).

Nestes casos, a BeginInvoke seria útil. Chamando-o, você está dizendo o delegado para começar, mas depois a sua discussão é livre para fazer outras coisas em paralelo com o delegado.

Usando BeginInvoke aumenta a complexidade do código, mas há momentos em que o melhor desempenho vale a complexidade.

A diferença entre Control.Invoke() e Control.BeginInvoke() é,

  • BeginInvoke() irá agendar a ação assíncrona no thread GUI. Quando a ação assíncrona está programado, o código continua. Algum tempo depois (você não sabe exatamente quando) sua ação assíncrona será executado
  • Invoke() executará sua ação assíncrona (no segmento GUI) e espere até que sua ação foi concluída.

A conclusão lógica é que um delegado que você passar para Invoke() pode ter out-parâmetros ou um valor de retorno, enquanto um delegado que você passar para BeginInvoke() não pode (você tem que usar EndInvoke para recuperar os resultados).

Apenas para dar um curto, exemplo de trabalho para ver um efeito de sua diferença

new Thread(foo).Start();

private void foo()
{
  this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
    (ThreadStart)delegate()
    {
        myTextBox.Text = "bing";
        Thread.Sleep(TimeSpan.FromSeconds(3));
    });
  MessageBox.Show("done");
}

Se o uso BeginInvoke , MessageBox aparece simultânea à atualização de texto. Se o uso Invoke , pops MessageBox após o segundo sono 3. Por isso, mostrando o efeito de um assíncrono ( BeginInvoke ) e um (Invoke ) chamada síncrona.

Delegate.BeginInvoke () de forma assíncrona filas a chamada de um delegado e retorna o controle imediatamente. Ao usar Delegate.BeginInvoke (), você deve chamar Delegate.EndInvoke () no método de retorno para obter os resultados.

Delegate.Invoke () sincronicamente chama o delegado no mesmo segmento.

MSDN artigo

Basta adicionar o porquê e quando usar Invoke ().

Ambos Invoke () e BeginInvoke () empacotar o código que você especificar para o segmento despachante.

Mas, ao contrário BeginInvoke (), Invoke () barracas seu segmento até o despachante executa seu código. Você pode querer usar Invoke () se você precisar pausar uma operação assíncrona até que o usuário tenha fornecido algum tipo de feedback.

Por exemplo, você poderia chamar Invoke () para executar um trecho de código que mostra um OK / caixa de diálogo Cancelar. Depois que o usuário clica em um botão e seus concluída código empacotado, o invoke () método irá retornar, e você pode agir de acordo com a resposta do usuário.

Veja Pro WPF em C # capítulo 31

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top