Pergunta

Eu vi a configuração comum para o acesso de segmentação cruzada para um controle GUI, tal como discutido aqui: caminho mais curto para gravação um método de acesso thread-safe para um controle Windows Forms

Toda a web bate eu encontrei descrever uma coisa semelhante.

No entanto, por que precisamos de verificar InvokeRequired? Não podemos simplesmente chamar Invoke diretamente?

Presumo que a resposta é não, então a minha verdadeira pergunta é 'porquê'?

Foi útil?

Solução

A partir tópicos não-UI não podemos tocar a interface do usuário - coisas muito ruins podem acontecer, uma vez que controles têm afinidade de segmento. Assim, a partir de um não-UI enfiar devemos (a uma minumum) Invoke chamada ou BeginInvoke.

Para UI-threads, no entanto - nós não quiser chamar lotes Invoke de tempo; a questão é que se você são já no segmento interface do usuário, ele ainda tem a sobrecarga desnecessária de enviar uma mensagem a bomba do formulário e processá-lo.

Na realidade, na maioria código de threading você sabe você espera um método específico para ser chamado em um não fio -ui, então, nesses casos, não há nenhum adicional sobrecarga:. apenas chamada Invoke

Outras dicas

InvokeRequired basicamente diz se você está executando no thread certo ou não. Se você não estiver na linha correta, você precisa organizar a tarefa para o segmento correto de outra forma você não. Daí a necessidade do cheque.

A questão é que os controles GUI tem uma exigência de que apenas código em execução no mesmo segmento que foi usado para instanciar o controle GUI pode acessar o controle GUI. As razões por trás desta exigência está ligada à forma como o Windows é arquitetado. Basta dizer, seria muito difícil mudar isso.

As verificações InvokeRequired a identidade da corrente thread em execução contra a identidade do segmento instantiating. Se eles são o mesmo, o código pode interagir livremente com o controle. Se não, o código deve empacotar os dados através do segmento atual para o segmento instantiating. Isto é um processo lento e dispendioso e é para ser evitada, se possível. Seu código irá funcionar se você sempre invocar e pode ser que você não vai notar o impacto no desempenho, mas este cenário vai ser cada vez mais comum como sistemas multi-core entrar em uso. É melhor não para criar código "nós" que têm de ser desfeita mais tarde.

Se você tentar invocar antes de um identificador de janela é criada (por exemplo, ao chamar forma construtor), você vai ter uma InvalidOperationException. Então, verificação geral InvokeRequired é necessária.

MSDN para mais detalhes.

Uma razão que eu posso pensar é performence. Se a maior parte do tempo, o segmento de chamada é o mesmo que o fio criando então você vai ter alguma sobrecarga unnessecry.

O Invoke vai chamar o código através do Delegado e não diretamente que seria caro.

Seu custo eficaz para chamar Invoke apenas quando necessário. Assim, InvokeRequired é usado para descobrir se a chamada está sendo feita a partir de mesmo segmento ou outro segmento?

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