remarks net example c# delegates anonymous-methods begininvoke

net - remarks c#



¿Método anónimo como parámetro para BeginInvoke? (6)

¿Por qué no puede pasar un método anónimo como parámetro al método BeginInvoke ? Tengo el siguiente código:

private delegate void CfgMnMnuDlg(DIServer svr); private void ConfigureMainMenu(DIServer server,) { MenuStrip mnMnu = PresenterView.MainMenu; if (mnMnu.InvokeRequired) { mnMnu.BeginInvoke((CfgMnMnuDlg)ConfigureMainMenu, new object[] { server}); } else { // Do actual work here } }

Estoy tratando de evitar declarar al delegado. ¿Por qué no puedo escribir algo como el siguiente en su lugar? ¿O puedo, y simplemente no puedo averiguar la sintaxis correcta? El siguiente genera actualmente un:

El tipo de argumento ''Método anónimo'' no se puede asignar al tipo de parámetro ''System.Delegate''

Ok, eso es correcto, por supuesto, pero ¿hay alguna otra sintaxis que pueda usar para hacer esto (evitar tener que declarar un delegado por separado para usar BeginInvoke() ?

(Ser capaz de hacer esto encajaría perfectamente con el concepto de utilizar métodos / lamdas anon en lugar de delegados explícitos que funcionan tan limpiamente en cualquier otro lugar).

private void ConfigureMainMenu(DIServer server,) { MenuStrip mnMnu = PresenterView.MainMenu; if (mnMnu.InvokeRequired) { mnMnu.BeginInvoke( // pass anonymous method instead ? delegate(DIServer svr) { ConfigureMainMenu(server);}, new object[] { server}); } else { // Do actual work here } }


Deberías poder escribir algo como esto:

private void ConfigureMainMenu(DIServer server,) { MenuStrip mnMnu = PresenterView.MainMenu; if (mnMnu.InvokeRequired) { mnMnu.BeginInvoke(new Action<DIServer>(ConfigureMainMenu), new object[] { server}); } else { // Do actual work here } }


He intentado un montón de métodos diferentes, pero ninguno funciona. es decir...

// Fails -- cannot convert lamda to System.Delegate mnMnu.BeginInvoke( (DIServer svr)=> {ConfigureMainMenu(server);}, new object[] server); // Fails -- cannot convert anonymous method to System.Delegate mnMnu.BeginInvoke( new delegate(DIServer svr){ConfigureMainMenu(server);}, new object[] server);

Entonces, la respuesta corta es no. Podrías crear delegados ayudantes cortos en el contexto dado y usar lambdas para hacerlo un poco más ordenado, pero eso es todo.

EDIT: Resulta que estoy equivocado. La respuesta de methodinvoker a continuación funciona. Ver esta page


Para métodos completamente anónimos con un número limitado de parámetros:

Func<int, int?> caller = new Func<int, int?>((int param1) => { return null; }); caller.BeginInvoke(7, new AsyncCallback((IAsyncResult ar) => { AsyncResult result = (AsyncResult)ar; Func<int, int?> action = (Func<int, int?>)result.AsyncDelegate; action.EndInvoke(ar); }), null);

Puede usar uno de los otros tipos de delegado funcional según sea necesario.


Prueba esto:

control.BeginInvoke((MethodInvoker) delegate { /* method details */ });

O:

private void ConfigureMainMenu(DIServer server) { if (control.InvokeRequired) { control.BeginInvoke(new Action<DIServer >(ConfigureMainMenu), server); } else { /* do work */ } }

O:

private void ConfigureMainMenu(DIServer server) { MenuStrip mnMnu = PresenterView.MainMenu; if (mnMnu.InvokeRequired) { // Private variable _methodInvoker = new MethodInvoker((Action)(() => ConfigureMainMenu(server))); _methodInvoker.BeginInvoke(new AsyncCallback(ProcessEnded), null); // Call _methodInvoker.EndInvoke in ProcessEnded } else { /* do work */ } }


Puedes escribir un método de extensión que envuelva métodos anónimos, e incluso cuidar la semántica InvokeRequired :

public static void InvokeAction(this Control ctl, Action a) { if (!ctl.InvokeRequired) { a(); } else { ctl.BeginInvoke(new MethodInvoker(a)); } }

Esto te permitiría hacer:

control.InvokeAction(delegate() { ConfigureMainMenu(server); });


Puedes hacer esto en un solo método llamando a invocarte a ti mismo:

ClassData updData = new ClassData(); this.BeginInvoke(new Action<ClassData>(FillCurve), new object[] { updData });

...

public void FillCurve(ClassData updData) { ... }