Parce que Invoke/ BeginInvokeaccepte Delegate(plutôt qu'un délégué typé), vous devez indiquer au compilateur le type de délégué à créer; MethodInvoker(2.0) ou Action(3.5) sont des choix courants (notez qu'ils ont la même signature); ainsi:
(mise en garde: vous devez être un peu prudent si vous utilisez des captures asynchrones , mais la synchronisation est bien - c'est-à-dire que ce qui précède est bien)
Une autre option consiste à écrire une méthode d'extension:
Si vous ne pouvez pas utiliser C # 3.0, vous pouvez faire la même chose avec une méthode d'instance régulière, probablement dans une Formclasse de base.
Comment puis-je passer des paramètres à votre première solution dans cette réponse? Je voulais dire cette solution: control.Invoke ((MethodInvoker) delegate {this.Text = "Hi";});
uzay95
1
Pourquoi la méthode d'extension est-elle appelée sans avoir à effectuer une conversion explicite en action?
P.Brian.Mackey
Parce que le compilateur peut déduire cela de l'utilisation.
RoboJ1M
1
C'est la même chose que de pouvoir faire à la Form.Load += Loader()place de l'ancienForm.Load += new EventHandler(Loader())
RoboJ1M
49
En fait, vous n'avez pas besoin d'utiliser le mot-clé de délégué. Passez simplement lambda comme paramètre:
Vous devez créer un type de délégué. Le mot-clé «délégué» dans la création de méthode anonyme est un peu trompeur. Vous ne créez pas un délégué anonyme mais une méthode anonyme. La méthode que vous avez créée peut être utilisée dans un délégué. Comme ça:
Par souci d'exhaustivité, cela peut également être accompli via une combinaison méthode Action / méthode anonyme:
//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);est la meilleure réponse, merci!
Jinjinov
5
J'ai eu des problèmes avec les autres suggestions car je veux parfois renvoyer des valeurs de mes méthodes. Si vous essayez d'utiliser MethodInvoker avec des valeurs de retour, cela ne semble pas plaire. Donc, la solution que j'utilise est comme ça (très heureux d'entendre un moyen de rendre cela plus succinct - j'utilise 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";}
Bonus: ajoutez une gestion des erreurs, car il est probable que, si vous utilisez à Control.Invokepartir d'un thread d'arrière-plan, vous mettez à jour l'état de texte / progression / activé d'un contrôle et ne vous souciez pas si le contrôle est déjà supprimé.
Form.Load += Loader()
place de l'ancienForm.Load += new EventHandler(Loader())
En fait, vous n'avez pas besoin d'utiliser le mot-clé de délégué. Passez simplement lambda comme paramètre:
la source
la source
Vous devez créer un type de délégué. Le mot-clé «délégué» dans la création de méthode anonyme est un peu trompeur. Vous ne créez pas un délégué anonyme mais une méthode anonyme. La méthode que vous avez créée peut être utilisée dans un délégué. Comme ça:
la source
Par souci d'exhaustivité, cela peut également être accompli via une combinaison méthode Action / méthode anonyme:
la source
Invoke((Action) Process);
est la meilleure réponse, merci!J'ai eu des problèmes avec les autres suggestions car je veux parfois renvoyer des valeurs de mes méthodes. Si vous essayez d'utiliser MethodInvoker avec des valeurs de retour, cela ne semble pas plaire. Donc, la solution que j'utilise est comme ça (très heureux d'entendre un moyen de rendre cela plus succinct - j'utilise c # .net 2.0):
la source
J'aime utiliser Action à la place de MethodInvoker, il est plus court et semble plus propre.
Par exemple.
la source
Je n'ai jamais compris pourquoi cela fait une différence pour le compilateur, mais c'est suffisant.
Bonus: ajoutez une gestion des erreurs, car il est probable que, si vous utilisez à
Control.Invoke
partir d'un thread d'arrière-plan, vous mettez à jour l'état de texte / progression / activé d'un contrôle et ne vous souciez pas si le contrôle est déjà supprimé.la source