Hoy en uno de los cursos de campusMVP un alumno me ha hecho una pregunta cuya respuesta creo que puede interesar a más de uno. Se refería a la llamada asíncrona a servicios Web y una segunda sobrecarag de los métodos xxxxAsync que toma un parámetro adicional.

como es sabido cuando definimos un servicio Web y lo consumimos desde una aplicación cliente es posible hacer llamadas asíncronas al mismo para dejar que se siga ejecutando la aplicaicón sin necesidad de quedar con el hilo a la espera de que terminen operaciones largas en dicho servicio. Desde .NET 2.0 esto es muy sencillo ya que el proxy que se genera para llamar al servicio añade para cada método un método adicional con el mismo nombre y seguido de la palabra "Async" de modo que podamos utilizarlo para hacer la llamada asíncrona. así, si tenemo sun método GetdatosFromClientes, podemos llamarlo asíncronamente con GetdatosFromClientesAsync.

Nota: Ojo porque si la referencia al servicio Web la añadimos usando WCF para generar el proxy y las llamadas deberemos marcar explícitamente que se generen los método asíncronos pues por defecto no lo hace:

Vale. Entonces la llamada síncrona es tan sencilla como asignar un método como método a llamar cuando regrese la llamada desde el servidor (ahí procesamos y obtenemos el resultado de la llamada al método), y llamar a este método xxxAsync sin parámetros.

No obstante el método Async tiene una sobrecarga que nos permite pasarle un objeto de referencia a la llamada. El objeto de este parámetro adicional en esta sobrecarga es el de añadir información de contexto a la llamada, generamente para distinguir unas de otras y/o añadir información contextual sobre la llamada si el manejador se reutiliza entre varias de ellas. Dado que le podemos pasar un objeto de una clase cualquiera definida por nosotros nos sirve para pasar cualquier tipo de información. Luego dicho objeto de contexto se recupera en el manejador del retorno de la llamada a través de la propiedad UserState del segundo parámetro de dicho método.

Veamos un ejemplo práctico de cómo usarlo. Imaginemos un método cualquiera de un servicio al que vamos a llamar asíncronamente (de nombre, por ejemplo, HelloWorld, da lo mismo). Lo llamamos varias veces (en nuestro ejemplo simplificado dentro de un bucle) y queremos visualizar por pantalla en qué orden se devuelven las llamadas asíncronas, que con mucha probabilidad no tiene porqué ser el mismo orden en el que fueron hechas. Podemos escribir este código (en VB):

Sub Main()
    Dim s As New WSEjemplo.ServiceSoapClient()
    AddHandler s.HelloWorldCompleted, AddressOf FinHola

    For i As Integer = 1 To 10
        s.HelloWorldAsync(i)
    Next
    
    Console.ReadLine()
End Sub

Private Sub FinHola(ByVal sender As Object, ByVal e As WSEjemplo.HelloWorldCompletedEventArgs)
   Dim idLlamada As Integer = CType(e.UserState, Integer)
   Console.WriteLine(idLlamada)
End Sub

Lo que conseguimos es que, tras cada llamada se obtiene el orden en el que se inició la misma desde la informción de contexto pasada con el método Async. Así veremos que el orden en el que se reciben las respuestas no es generalmente el original de las llamadas, por ejemplo el de la figura:

Como vemos en este ejemplo práctico sencillo, esta segunda sobrecarga de las llamadas asíncronas puede sernos de mucha utilidad para sincronizar o distinguir por contexto unas llamadas asíncronas de otras.

Espero que te sea útil!

💪🏻 ¿Este post te ha ayudado?, ¿has aprendido algo nuevo?
Pues NO te pido que me invites a un café... Te pido algo más fácil y mucho mejor