Como Invoke/ BeginInvokeaceita Delegate(em vez de um delegado digitado), você precisa informar ao compilador que tipo de delegado criar; MethodInvoker(2.0) ou Action(3.5) são escolhas comuns (observe que elas têm a mesma assinatura); igual a:
Como posso passar parâmetros para sua primeira solução nesta resposta? Eu quis dizer esta solução: control.Invoke ((MethodInvoker) delegate {this.Text = "Hi";});
uzay95
1
Por que o método de extensão é chamado sem ter que fazer uma conversão explícita para a ação?
usar o seguinte código
Porque o compilador pode inferir isso do uso.
21416 RoboJ1M
1
É o mesmo que ser capaz de fazer Form.Load += Loader()em vez do antigoForm.Load += new EventHandler(Loader())
RoboJ1M
49
Na verdade, você não precisa usar a palavra-chave delegada. Apenas passe lambda como parâmetro:
Você precisa criar um tipo de delegado. A palavra-chave 'delegar' na criação do método anônimo é um pouco enganadora. Você não está criando um delegado anônimo, mas um método anônimo. O método que você criou pode ser usado em um delegado. Como isso:
Por uma questão de integridade, isso também pode ser realizado por meio de uma combinação de método Action / método anônimo:
//Process is a method, invoked as a method groupDispatcher.Current.BeginInvoke((Action)Process);//or use an anonymous methodDispatcher.Current.BeginInvoke((Action)delegate=>{SomeFunc();SomeOtherFunc();});
Invoke((Action) Process);é a melhor resposta, obrigado!
Jinjinov 19/03
5
Eu tive problemas com as outras sugestões porque às vezes quero retornar valores dos meus métodos. Se você tentar usar o MethodInvoker com valores de retorno, não parece gostar. Portanto, a solução que uso é a seguinte (muito feliz em ouvir uma maneira de tornar isso mais sucinto - estou usando o c # .net 2.0):
// Create delegates for the different return types needed.privatedelegatevoidVoidDelegate();privatedelegateBooleanReturnBooleanDelegate();privatedelegateHashtableReturnHashtableDelegate();// Now use the delegates and the delegate() keyword to create // an anonymous method as required// Here a case where there's no value returned:publicvoidSetTitle(string title){
myWindow.Invoke(newVoidDelegate(delegate(){
myWindow.Text= title;}));}// Here's an example of a value being returnedpublicHashtableCurrentlyLoadedDocs(){return(Hashtable)myWindow.Invoke(newReturnHashtableDelegate(delegate(){return myWindow.CurrentlyLoadedDocs;}));}
// Thread-safe update on a form controlpublicvoidDisplayResult(string text){if(txtResult.InvokeRequired){
txtResult.Invoke((Action)delegate{DisplayResult(text);});return;}
txtResult.Text+= text +"\r\n";}
Bônus: adicione algum tratamento de erro, porque é provável que, se você estiver usando Control.Invokede um encadeamento em segundo plano, esteja atualizando o texto / progresso / estado ativado de um controle e não se importe se o controle já estiver descartado.
Form.Load += Loader()
em vez do antigoForm.Load += new EventHandler(Loader())
Na verdade, você não precisa usar a palavra-chave delegada. Apenas passe lambda como parâmetro:
fonte
fonte
Você precisa criar um tipo de delegado. A palavra-chave 'delegar' na criação do método anônimo é um pouco enganadora. Você não está criando um delegado anônimo, mas um método anônimo. O método que você criou pode ser usado em um delegado. Como isso:
fonte
Por uma questão de integridade, isso também pode ser realizado por meio de uma combinação de método Action / método anônimo:
fonte
Invoke((Action) Process);
é a melhor resposta, obrigado!Eu tive problemas com as outras sugestões porque às vezes quero retornar valores dos meus métodos. Se você tentar usar o MethodInvoker com valores de retorno, não parece gostar. Portanto, a solução que uso é a seguinte (muito feliz em ouvir uma maneira de tornar isso mais sucinto - estou usando o c # .net 2.0):
fonte
Eu gosto de usar o Action no lugar do MethodInvoker, é mais curto e parece mais limpo.
Por exemplo.
fonte
Eu nunca entendi por que isso faz diferença para o compilador, mas isso é suficiente.
Bônus: adicione algum tratamento de erro, porque é provável que, se você estiver usando
Control.Invoke
de um encadeamento em segundo plano, esteja atualizando o texto / progresso / estado ativado de um controle e não se importe se o controle já estiver descartado.fonte