Pergunta

Eu entendo que em .NET, é preciso usar Control.Invoke (delegado) para executar operações em um controle. Isso me leva a querer saber em quais ambientes Invoke é realmente necessário. Tanto quanto eu sei, não foi necessária em versões mais antigas do, digamos, Visual Basic e Pascal. Em particular, qual é o status de Java (possivelmente? Dependente da versão) e programação GUI janelas "estilo antigo" (leitura manualmente a fila de mensagens)?

Foi útil?

Solução

Na maioria das linguagens Invoke para operações de GUI é necessário. Em Java existe SwingUtilities.invokeLater . Na verdade, um método como que seria necessário em qualquer ambiente se forem utilizados mais de threads. A razão é que o principal segmento interface do usuário executa um mecanismo de notificação de eventos. Um segundo segmento para ser capaz de interagir com este mecanismo precisa de alguma forma para ser sincronizado com ele.

Estes métodos invocar são realmente uma conveniência para o desenvolvedor. Em plataformas que não existem, isso não significa que é permitido para itens de acesso de interface do usuário de um thread diferente. Pode ser apenas significa que o desenvolvedor deve implementar um mecanismo de costume (o envio de eventos) para fazê-lo. código de interface do usuário é muito raramente o segmento de seguros. Eu tenho trabalhado com muitas plataformas e tecnologias e estou sempre seguindo esta regra:. Toque na interface do usuário a partir de apenas um único segmento

Outras dicas

Você está enganado. Control.Invoke não é obrigado a executar operações em um controle.

Control.Invoke é uma ferramenta útil para ajudar código marshall além das fronteiras de rosca, mas não é a única maneira de fazê-lo. Você vai ver isso usado na maioria das vezes quando você faz algum trabalho em uma discussão de fundo.

Quando você chamar o código a partir de uma discussão de fundo que deve atualizar um controle de janela (isto é, um controle que tem uma alça janela do Windows e processa mensagens via bomba de mensagem), alterar suas propriedades, ou alguma outra manipulação do controle, então você deve passar o controle para o segmento MessagePump e Control.Invoke é uma maneira útil para acocmplish isso.

Em ALL programas que são executados no Windows, você não pode chamar funções que atualizar controles em uma discussão de fundo. Alguns idiomas podem lidar com esse detalhe no fundo, mas eu não sei de nenhum que fazer.

Invoke é apenas um invólucro em torno da API PostMessage Win32. Somente o segmento que possui uma janela tem permissão para acessar a janela. Este é o legado indo todo o caminho de volta para quando o Windows foi único segmento. Isso significa que PostMessage é a maneira correta de acesso uma verdadeira janela para o Windows não importa o que você está usando (VB6, Delphi, .NET, ou qualquer outro), mas as diferentes linguagens de programação fornecem wrappers para tornar a vida mais fácil para nós.

Na verdade, não. Isso só é necessário se você estiver GUI está em execução mais de 1 fio. Com WinForm (e WPF) aplicativos da GUI está em execução em um único segmento STA rosca (este remonta a COM e não me pergunte por que é assim, porque eu honestamente não sei).

Se você tentar chamada objetos criados no thread STA de um thread diferente, há verificações no local para certificar-se de uma exceção é lançada. Este mesmo acontece com WPF embora, WPF torna isso muito mais elegante.

De qualquer forma, você pode realmente verificar quando Invoke é necessária porque há uma propriedade para isso. Este padrão tem sido sugerido para ajuda com a manipulação de vários tópicos em aplicações WinForm.

public void MyTextSetMethod(string text)
{
    if(control.InvokeRequired)
    {
        control.Invoke(new Action<string>(MyTextSetMethod), text);
    }
    else
    {
        control.Text = text;
    }
}

O código acima fornece tudo método volta para definir a propriedade de texto, você pode adaptar isso para atender às suas necessidades.

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