Método anónimo en Invocar llamada

Tener un problema con la syntax en la que queremos llamar a un delegado de forma anónima dentro de Control.Invocar.

Hemos intentado una serie de enfoques diferentes, todo fue en vano.

Por ejemplo:

myControl.Invoke(delegate() { MyMethod(this, new MyEventArgs(someParameter)); }); 

donde algún parámetro es local para este método

Lo anterior dará como resultado un error de comstackción:

No se puede convertir el método anónimo para escribir ‘System.Delegate’ porque no es un tipo de delegado

Como Invoke / BeginInvoke acepta Delegate (en lugar de un delegado tipeado), necesita decirle al comstackdor qué tipo de delegado crear; MethodInvoker (2.0) o Action (3.5) son opciones comunes (tenga en cuenta que tienen la misma firma); al igual que:

 control.Invoke((MethodInvoker) delegate {this.Text = "Hi";}); 

Si necesita pasar parámetros, entonces las “variables capturadas” son la forma:

 string message = "Hi"; control.Invoke((MethodInvoker) delegate {this.Text = message;}); 

(advertencia: debes ser un poco cauteloso si usas capturas asincrónicas , pero la sincronización es correcta , es decir, lo anterior está bien)

Otra opción es escribir un método de extensión:

 public static void Invoke(this Control control, Action action) { control.Invoke((Delegate)action); } 

entonces:

 this.Invoke(delegate { this.Text = "hi"; }); // or since we are using C# 3.0 this.Invoke(() => { this.Text = "hi"; }); 

Por supuesto, puede hacer lo mismo con BeginInvoke :

 public static void BeginInvoke(this Control control, Action action) { control.BeginInvoke((Delegate)action); } 

Si no puede usar C # 3.0, podría hacer lo mismo con un método de instancia regular, presumiblemente en un Form de clase base.

En realidad, no es necesario utilizar la palabra clave delegar. Solo pase lambda como parámetro:

 control.Invoke((MethodInvoker)(() => {this.Text = "Hi"; })); 
 myControl.Invoke(new MethodInvoker(delegate() {...})) 

Necesita crear un tipo de delegado. La palabra clave ‘delegar’ en la creación de métodos anónimos es un poco engañosa. No está creando un delegado anónimo, sino un método anónimo. El método que creó se puede usar en un delegado. Me gusta esto:

 myControl.Invoke(new MethodInvoker(delegate() { (MyMethod(this, new MyEventArgs(someParameter)); })); 

En aras de la exhaustividad, esto también se puede lograr a través de una combinación método de acción / método anónimo:

 //Process is a method, invoked as a method group Dispatcher.Current.BeginInvoke((Action) Process); //or use an anonymous method Dispatcher.Current.BeginInvoke((Action)delegate => { SomeFunc(); SomeOtherFunc(); }); 

Tuve problemas con las otras sugerencias porque a veces deseo devolver valores de mis métodos. Si intenta utilizar MethodInvoker con valores devueltos, parece que no le gusta. Entonces la solución que uso es así (muy feliz de escuchar una manera de hacer esto más breve, estoy usando c # .net 2.0):

  // Create delegates for the different return types needed. private delegate void VoidDelegate(); private delegate Boolean ReturnBooleanDelegate(); private delegate Hashtable ReturnHashtableDelegate(); // Now use the delegates and the delegate() keyword to create // an anonymous method as required // Here a case where there's no value returned: public void SetTitle(string title) { myWindow.Invoke(new VoidDelegate(delegate() { myWindow.Text = title; })); } // Here's an example of a value being returned public Hashtable CurrentlyLoadedDocs() { return (Hashtable)myWindow.Invoke(new ReturnHashtableDelegate(delegate() { return myWindow.CurrentlyLoadedDocs; })); }