Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En el ejemplo Reentrant se muestra la necesidad y las implicaciones de usar ConcurrencyMode.Reentrant en una implementación de servicio. ConcurrencyMode.Reentrant implica que el servicio (o callback) procesa solo un mensaje a la vez (similar a ConcurencyMode.Single). Para garantizar la seguridad de los subprocesos, Windows Communication Foundation (WCF) bloquea el InstanceContext procesamiento de un mensaje 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 demostrar el comportamiento, el ejemplo muestra cómo un cliente y un servicio pueden enviar mensajes entre sí mediante un contrato dúplex.
El contrato definido es un contrato dúplex con el método Ping implementado por el servicio y el método de devolución de llamada Pong 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. Esto se realiza mediante el código siguiente 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));
}
}
Los métodos Ping y Pong son de tipo request/reply, lo que significa que la primera llamada a Ping no retorna hasta que la llamada a CallbackChannel<T>.Pong() ha retornado. En el cliente, el método Pong no puede retornar hasta que la llamada Ping siguiente que se realizó retorne. 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.
Para configurar, compilar y ejecutar el ejemplo
Asegúrese de que ha realizado el procedimiento de instalación única para los ejemplos de Windows Communication Foundation.
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.
Para ejecutar el ejemplo en una configuración de una máquina única o entre máquinas, siga las instrucciones de Ejecución de los ejemplos de Windows Communication Foundation.
Demostraciones
Para ejecutar el ejemplo, compile los proyectos de cliente y servidor. 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