none
Pasar parámetros a callback RRS feed

  • Pregunta

  • Buenas tardes,

    estoy haciendo un procedimiento asíncrono; y quiero que cuando se ejecute el método callback, reciba los parámetros del método delegado invocado: (Quiero recuperar los calores de los parámetros al finalizar el proceso)

                                                            

    No se como hacerlo, gracias:

                        AsyncCallback myAsyncCallback = new AsyncCallback(MiCallback);

                        Midelegado method = new Midelegado(Enviardeformaasincrona);

                        IAsyncResult a = method.BeginInvoke(fila["correoelectronico"].ToString(), fila["codcliente"].ToString(), fila["nombre"].ToString(),myAsyncCallback, null);

                    }

                    i = i + 1;
                }

            }

            private  void MiCallback(IAsyncResult ar)
            {

                System.Runtime.Remoting.Messaging.AsyncResult result = (System.Runtime.Remoting.Messaging.AsyncResult)ar;


                // recuperamos el delegado para hacer EndInvoke
                Midelegado delegado = (Midelegado)result.AsyncDelegate;

                delegado.EndInvoke(ar);
            }

    www.rivassistemas.com

    jueves, 7 de enero de 2021 18:51

Respuestas

  • Para eso se usa el AsyncState.

    Fíjate en el último null que pasas al final del BeginInvoke. Normalmente ese es el parámetro que se conoce como AsyncState. Es de tipo Object, por lo que ahí puedes pasar "cualquier cosa". Puede ser de una clase definida por ti y que contenga múltiples propiedades en su interior.

    Pues bien, durante el callback, lo que hayas pasado en ese parámetro (que podría ser una copia del resto de los argumentos, si es que así lo quieres), se recupera simplemente llamando a ar.AsyncState. Obviamente, y dado que es de tipo object, tienes que hacerle un "cast" al tipo correcto antes de usarlo.

    jueves, 7 de enero de 2021 21:21
    Moderador

Todas las respuestas

  • Hola,

    Gracias por levantar tu consulta en los foros de MSDN.

    Eric Ruiz

    ____________________________

    Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde.

    Si tiene algún cumplido o reclamo sobre el soporte de MSDN siéntase en la libertad de contactar MSDNFSF@microsoft.com.

    jueves, 7 de enero de 2021 20:27
    Moderador
  • Para eso se usa el AsyncState.

    Fíjate en el último null que pasas al final del BeginInvoke. Normalmente ese es el parámetro que se conoce como AsyncState. Es de tipo Object, por lo que ahí puedes pasar "cualquier cosa". Puede ser de una clase definida por ti y que contenga múltiples propiedades en su interior.

    Pues bien, durante el callback, lo que hayas pasado en ese parámetro (que podría ser una copia del resto de los argumentos, si es que así lo quieres), se recupera simplemente llamando a ar.AsyncState. Obviamente, y dado que es de tipo object, tienes que hacerle un "cast" al tipo correcto antes de usarlo.

    jueves, 7 de enero de 2021 21:21
    Moderador
  • Gracias amigo, muy buena explicación, hice la prueba y funciona correctamente, lo probé con variables y con clases. Por otro lado, (creo que debo hacer una pregunta aparte), cuando paso otro objeto, en este caso un listboxControl al callback me envía el siguiente mensaje: System.InvalidOperationException: 'Cross-thread operation not valid: Control 'listBoxControl1' accessed from a thread other than the thread it was created on.'

    Es decir, si dentro del callback hago

    listBoxControl1.Items.Add("finalizado");

    directamente sobre el control me da ese mensaje, y si lo envío como parámetro al callback:

    ListBoxControl lis =(ListBoxControl)ar.AsyncState;
    lis.Items.Add("finalizado");

    también me da el mismo error en el método Add() de ese objeto

    Cómo podría solucionar eso?. Gracias, muchas gracias amigo.


    domingo, 10 de enero de 2021 0:16
  • Ah, eso es otra cosa distinta. No está causado por el hecho de que el ListBox lo hayas pasado dentro del AsyncState, sino porque el código que accede al ListBox se ejecuta desde otro Thread. Los controles usados en las aplicaciones de escritorio son "mono-hilo", que quiere decir que solo se pueden usar desde el hilo que los creó, pero no están preparados para que se pueda acceder a ellos desde múltiples hilos sin que se corrompan.

    Para soslayar este problema, cuando necesitas acceder a un control desde otro hilo, hay que trasvasar la ejecución al hilo principal utilizando el método Invoke (o BeginInvoke) de cualquier control, incluyendo el propio Form. Esto se haría más o menos así:

    ListBoxControl lis =(ListBoxControl)ar.AsyncState;
    lis.Invoke(new MethodInvoker(() => lis.Items.Add("finalizado")));
     
    

    Desde luego, se puede hacer de muchas otras formas. Te lo he escrito con una Lambda por brevedad.

    OJO, hay que entender bien lo que estás haciendo y comprender las consecuencias. Al trasvasar la ejecución al hilo principal, esto implica que se quedará ahí atascado si en ese momento el hilo principal está ocupado haciendo otra cosa.

    domingo, 10 de enero de 2021 9:07
    Moderador
  • Excelente, funciona muy bien, gracias!!!!
    domingo, 10 de enero de 2021 16:14