Compartir a través de


Cómo llamar a operaciones de manera asincrónica mediante un generador de canales

En este tema se cubre cómo un cliente puede obtener acceso de forma asincrónica a una operación del servicio al utilizar una aplicación de cliente basada en ChannelFactory. (Al utilizar un objeto System.ServiceModel.ClientBase para invocar un servicio, puede utilizar el modelo de llamada asincrónica orientado a eventos. Para obtener más información, consulte Cómo llamar a operaciones del servicio WCF de forma asincrónica. Para obtener más información sobre el modelo de llamada asincrónica basada en eventos, vea Multithreaded Programming with the Event-based Asynchronous Pattern).

El servicio en este tema implementa la interfaz ICalculator. El cliente puede llamar a las operaciones en esta interfaz de forma asincrónica, lo que significa que las operaciones como Add se dividen en dos métodos, BeginAdd y EndAdd, de los cuales el primero inicia la llamada y el segundo recupera el resultado cuando la operación termina. Para obtener un ejemplo que muestra cómo implementar de forma asincrónica una operación en un servicio, vea Cómo: Implementar una operación de servicios asincrónica. Para obtener información detallada de las operaciones sincrónicas y asincrónicas, vea Operaciones sincrónicas y asincrónicas.

Procedimiento

Para llamar a operaciones de servicio WCF de forma asincrónica

  1. Ejecute la herramienta Herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe) con la opción /async tal y como se muestra en el comando siguiente.

    svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples https://localhost:8000/servicemodelsamples/service/mex /a
    

    Esto genera una versión de cliente asincrónica del contrato de servicio para la operación.

  2. Cree una función de devolución de llamada a la que se va a llamar cuando la operación asincrónica haya finalizado, tal y como aparece en el siguiente código de ejemplo.

    Private Shared Sub AddCallback(ByVal ar As IAsyncResult)
        Dim result = (CType(ar.AsyncState, CalculatorClient)).EndAdd(ar)
        Console.WriteLine("Add Result: {0}", result)
    End Sub
    
    static void AddCallback(IAsyncResult ar)
    {
        double result = ((CalculatorClient)ar.AsyncState).EndAdd(ar);
        Console.WriteLine("Add Result: {0}", result);
    }
    
  3. Para obtener acceso de forma asincrónica a una operación de servicio, cree el cliente y llame a Begin[Operation] (por ejemplo, BeginAdd) y especifique una función de devolución de llamada, tal y como se muestra en el siguiente código de ejemplo.

    Dim factory As New ChannelFactory(Of ICalculatorChannel)()
    Dim channelClient As ICalculatorChannel = factory.CreateChannel()
    
    ' BeginAdd
      Dim value1 = 100.0R
      Dim value2 = 15.99R
    
    Dim arAdd As IAsyncResult = channelClient.BeginAdd(value1, value2, AddressOf AddCallback, channelClient)
    Console.WriteLine("Add({0},{1})", value1, value2)
    
    ChannelFactory<ICalculatorChannel> factory = new ChannelFactory<ICalculatorChannel>();
    ICalculatorChannel channelClient = factory.CreateChannel();
    
    // BeginAdd
    double value1 = 100.00D;
    double value2 = 15.99D;
    
    IAsyncResult arAdd = channelClient.BeginAdd(value1, value2, AddCallback, channelClient);
    Console.WriteLine("Add({0},{1})", value1, value2);
    

    Cuando la función de devolución de llamada se ejecuta, el cliente llama a End<operation>``EndAdd (por ejemplo, ) para recuperar el resultado.

Ejemplo

El servicio que se usa con el código de cliente que se utiliza en el procedimiento anterior implementa la interfaz ICalculator tal y como se muestra en el código siguiente. En el lado del servicio, el tiempo de ejecución de Windows Communication Foundation (WCF) invoca de manera sincrónica a las operaciones Add y Subtract del contrato, aunque los pasos precedentes del cliente se invoquen de manera asincrónica en el cliente. Las operaciones Divide y Multiply se utilizan para invocar de forma asincrónica el servicio en el lado del servicio, incluso aunque el cliente los invoque de forma sincrónica. Este ejemplo establece la propiedad AsyncPattern en true. Este valor de la propiedad, en combinación con la implementación del modelo asincrónico .NET Framework, indica al tiempo de ejecución para invocar la operación de forma asincrónica.

<ServiceContract(Namespace := "http://Microsoft.ServiceModel.Samples")> _
Public Interface ICalculator
    <OperationContract> _
    Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double

    <OperationContract> _
    Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double

    'Multiply involves some file I/O so we'll make it Async.
    <OperationContract(AsyncPattern := True)> _
    Function BeginMultiply(ByVal n1 As Double, ByVal n2 As Double, ByVal callback As AsyncCallback, ByVal state As Object) As IAsyncResult
    Function EndMultiply(ByVal ar As IAsyncResult) As Double

    'Divide involves some file I/O so we'll make it Async.
    <OperationContract(AsyncPattern := True)> _
    Function BeginDivide(ByVal n1 As Double, ByVal n2 As Double, ByVal callback As AsyncCallback, ByVal state As Object) As IAsyncResult
    Function EndDivide(ByVal ar As IAsyncResult) As Double
End Interface
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [OperationContract]
    double Add(double n1, double n2);

    [OperationContract]
    double Subtract(double n1, double n2);

    //Multiply involves some file I/O so we'll make it Async.
    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginMultiply(double n1, double n2, AsyncCallback callback, object state);
    double EndMultiply(IAsyncResult ar);

    //Divide involves some file I/O so we'll make it Async.
    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginDivide(double n1, double n2, AsyncCallback callback, object state);
    double EndDivide(IAsyncResult ar);
}

Vea también

Tareas

Asincrónico