Cómo: Implementar un cliente de servicio Web asincrónico con la técnica de devolución de llamada

La técnica de devolución de llamada es una manera de implementar un cliente de servicios web para comunicar de forma asincrónica con un método de servicio web, aunque el método se puede pensar para el acceso sincrónico. La técnica se explica en el tema Comunicación de forma asincrónica con Servicios web XML.

Este ejemplo está basado en un servicio web clase PrimeFactorizer con un método Factorize, para el que la herramienta Wsdl.exe ha generado dos métodos de proxy de cliente asincrónicos, BeginFactorize y EndFactorize.

Para implementar la técnica de devolución de llamada

  1. Defina una función de devolución de llamada que implementa el delegado AsyncCallback.

    public static void FactorizeCallback(IAsyncResult ar)
    
    Public Shared Sub FactorizeCallback(ar As IAsyncResult)
    
  2. Cree instancias del delegado AsyncCallback.

    AsyncCallback cb = new AsyncCallback(TestCallback.FactorizeCallback);
    
    Dim cb as AsyncCallback 
    cb = new AsyncCallback(AddressOf TestCallback.FactorizeCallback)
    
  3. Llame al método Begin, pasando la función de devolución de llamada como el segundo argumento y un objeto proporcionando estado (en este ejemplo, la implementación del cliente de PrimeFactorizer) como el tercer argumento.

    IAsyncResult ar = pf.BeginFactorize(factorizableNum, cb, pf);
    
    Dim ar As IAsyncResult = pf.BeginFactorize(factorizableNum, _
                                                         cb, pf)
    
  4. Compruebe la propiedad IsCompleted de IAsyncResult devuelta por el método Begin. El valor se establece como verdadero después de que el cliente haya recibido una respuesta del servidor.

  5. Dentro de la función de devolución de llamada, obtenga acceso al objeto de estados. La propiedad AsyncState del parámetro IAsyncState tiene el objeto pasado como tercer parámetro al método Begin.

    PrimeFactorizer pf = (PrimeFactorizer) ar.AsyncState;
    
    Dim pf As PrimeFactorizer = ar.AsyncState
    
  6. Dentro de la función de devolución de llamada, llame al método End en el objeto de estados obtenido en el paso anterior.

    long[] results = pf.EndFactorize(ar);
    
    Dim results() as Long
    results = pf.EndFactorize(ar)
    

Ejemplo

using System;
using System.Runtime.Remoting.Messaging;
using MyFactorize;

class TestCallback
 {           
      public static void Main(){
            long factorizableNum = 12345;
            PrimeFactorizer pf = new PrimeFactorizer();

            //Instantiate an AsyncCallback delegate to use as a parameter
            //in the BeginFactorize method.
            AsyncCallback cb = new AsyncCallback(TestCallback.FactorizeCallback);

          // Begin the Async call to Factorize, passing in our
          // AsyncCalback delegate and a reference
          // to our instance of PrimeFactorizer.
            IAsyncResult ar = pf.BeginFactorize(factorizableNum, cb, pf);
            
            // Keep track of the time it takes to complete the async call
            // as the call proceeds.
         int start = DateTime.Now.Second;
         int currentSecond = start;
         while (!ar.IsCompleted){
            if (currentSecond < DateTime.Now.Second) {
                  currentSecond = DateTime.Now.Second;
                  Console.WriteLine("Seconds Elapsed..." + (currentSecond - start).ToString() );
            }
         }
         // Once the call has completed, you need a method to ensure the
         // thread executing this Main function 
         // doesn't complete prior to the call-back function completing.
         Console.Write("Press Enter to quit");
         int quitchar = Console.Read();
      }
      // Set up a call-back function that is invoked by the proxy class
      // when the asynchronous operation completes.
      public static void FactorizeCallback(IAsyncResult ar)
      {
          // You passed in our instance of PrimeFactorizer in the third
          // parameter to BeginFactorize, which is accessible in the
          // AsyncState property.
          PrimeFactorizer pf = (PrimeFactorizer) ar.AsyncState;
          long[] results;

          // Get the completed results.
            results = pf.EndFactorize(ar);
          
          //Output the results.
            Console.Write("12345 factors into: ");
            int j;
            for (j = 0; j<results.Length;j++){
                  if (j == results.Length - 1)
                      Console.WriteLine(results[j]);
                  else 
                      Console.Write(results[j] + ", ");
            }
      }
}
Imports System
Imports System.Runtime.Remoting.Messaging
Imports MyFactorize

Public Class TestCallback
    Public Shared Sub Main()
       Dim factorizableNum As Long = 12345
       Dim pf As PrimeFactorizer = new PrimeFactorizer()

       'Instantiate an AsyncCallback delegate to use as a 
       'parameter
       ' in the BeginFactorize method.
       Dim cb as AsyncCallback 
       cb = new AsyncCallback(AddressOf TestCallback.FactorizeCallback)

     ' Begin the Async call to Factorize, passing in the
     ' AsyncCallback delegate and a reference to our instance
     ' of PrimeFactorizer.
       Dim ar As IAsyncResult = pf.BeginFactorize(factorizableNum, _
                                                     cb, pf)
            
     ' Keep track of the time it takes to complete the async call as
     ' the call proceeds.
       Dim start As Integer = DateTime.Now.Second
       Dim currentSecond As Integer = start
       Do while (ar.IsCompleted = false)
          If (currentSecond < DateTime.Now.Second) Then
                currentSecond = DateTime.Now.Second
                Console.WriteLine("Seconds Elapsed..." + 
                      (currentSecond - start).ToString() )
          End If
       Loop

      ' Once the call has completed, you need a method to ensure the
      ' thread executing this Main function 
      ' doesn't complete prior to the callback function completing.
       Console.Write("Press Enter to quit")
       Dim quitchar As Integer = Console.Read()
    End Sub

    ' Set up the call-back function that is invoked by the proxy 
    ' class when the asynchronous operation completes.
    Public Shared Sub FactorizeCallback(ar As IAsyncResult)
    
       ' You passed in the instance of PrimeFactorizer in the third
       ' parameter to BeginFactorize, which is accessible in the
       ' AsyncState property.
         Dim pf As PrimeFactorizer = ar.AsyncState
         Dim results() as Long

       ' Get the completed results.
         results = pf.EndFactorize(ar)
        
       'Output the results.
         Console.Write("12345 factors into: ")
         Dim j as Integer
         For j = 0 To results.Length - 1
              If  j = (results.Length - 1) Then
                   Console.WriteLine(results(j) )
              Else 
                   Console.Write(results(j).ToString + ", ")
              End If
        Next j         
     End Sub      
End Class

Consulte también

Tareas

Cómo: Implementar un cliente de servicio web asincrónico con la técnica de espera
Cómo: Realizar una llamada asincrónica desde un cliente de servicios web

Conceptos

Comunicar de forma asincrónica con servicios web XML
Generar clientes de servicios web XML

Otros recursos

Crear clientes de servicios web XML

Copyright © 2007 Microsoft Corporation. Reservados todos los derechos.