Compartir a través de


ConcurrencyMode reentrante

El ejemplo de reentrante muestra la necesidad y las implicaciones de usar ConcurrencyMode.Reentrant en una implementación del servicio. ConcurrencyMode.Reentrant implica que el servicio (o la devolución de llamada) procesa solo uno mensaje en una hora determinada (análogo a ConcurencyMode.Single). Para garantizar la seguridad para subprocesos, Windows Communication Foundation (WCF) bloquea el procesamiento de un mensaje InstanceContext para que no se puedan procesar otros mensajes. En el caso del modo reentrante, InstanceContext se desbloquea justo antes de que el servicio haga una llamada de salida por la que permite la llamada subsiguiente, (que puede ser reentrante como se muestra en el ejemplo) para obtener el bloqueo la próxima vez que entre al servicio. Para mostrar el comportamiento, el ejemplo muestra cómo un cliente y el servicio pueden enviar los mensajes entre sí utilizando un contrato dúplex.

El contrato definido es un contrato dúplex con el método Ping siendo implementado por el servicio y el método de devolución de llamadaPongsiendo implementado por el cliente. Un cliente invoca el método del servidor Ping con un recuento del paso que inicia así la llamada. El servicio comprueba si el recuento del paso no es igual a 0 y a continuación, invoca las devoluciones de llamada el método Pong disminuyendo el recuento del paso. El código siguiente realiza esta operación en el ejemplo.

public void Ping(int ticks)
{
     Console.WriteLine("Ping: Ticks = " + ticks);
     //Keep pinging back and forth till Ticks reaches 0.
     if (ticks != 0)
     {
         OperationContext.Current.GetCallbackChannel<IPingPongCallback>().Pong((ticks - 1));
     }
}

La implementación Pong de la devolución de llamada tiene la misma lógica que la implementación Ping. Es decir, comprueba si el contador no es cero y, a continuación, invoca el método Ping en el canal de devolución de llamada (en este caso, es el canal que fue utilizado para enviar el mensaje Ping original) con el contador disminuido en 1. El momento en que el contador llegue a 0, el método vuelve y desempaqueta de nuevo todas las respuestas a la primera llamada realizada por el cliente que inició la llamada. Esto se muestra en la implementación de devolución de llamada.

public void Pong(int ticks)
{
    Console.WriteLine("Pong: Ticks = " + ticks);
    if (ticks != 0)
    {
        //Retrieve the Callback  Channel (in this case the Channel which was used to send the
        //original message) and make an outgoing call until ticks reaches 0.
        IPingPong channel = OperationContext.Current.GetCallbackChannel<IPingPong>();
        channel.Ping((ticks - 1));
    }
}

Ping y los métodos Pong son solicitud/respuesta, lo cual significa que la primera llamada a Ping no vuelve hasta que la llamada CallbackChannel<T>.Pong()se devuelve. En el cliente, el método Pong no puede devolverse hasta que la siguiente llamada Ping que se realizó se devuelva. Dado que la devolución de llamada y el servicio deben realizar llamadas de salida de solicitud/respuesta antes de poder responder a la solicitud pendiente, las implementaciones se deben marcar con el comportamiento de ConcurrencyMode.Reentrant.

Configurar, compilar y ejecutar el ejemplo

  1. Asegúrese de que ha realizado el procedimiento de instalación única para los ejemplos de Windows Communication Foundation.

  2. Para compilar el código C# o Visual Basic .NET Edition de la solución, siga las instrucciones de Building the Windows Communication Foundation Samples.

  3. Para ejecutar el ejemplo en una configuración de un solo equipo o de varios, siga las instrucciones de Ejecución de ejemplos de Windows Communication Foundation.

Muestra

Para ejecutar el ejemplo, compile los proyectos de servidor y cliente. A continuación, abra dos ventanas de comandos y cambie los directorios a los directorios <sample>\CS\Service\bin\debug y <sample>\CS\Client\bin\debug. A continuación, inicie el servicio al escribir service.exe y, a continuación, invoque Client.exe con el valor inicial de los pasos pasados como argumento de entrada. Se muestra un resultado del ejemplo para 10 pasos.

Prompt>Service.exe
ServiceHost Started. Press Enter to terminate service.
Ping: Ticks = 10
Ping: Ticks = 8
Ping: Ticks = 6
Ping: Ticks = 4
Ping: Ticks = 2
Ping: Ticks = 0

Prompt>Client.exe 10
Pong: Ticks = 9
Pong: Ticks = 7
Pong: Ticks = 5
Pong: Ticks = 3
Pong: Ticks = 1