Condividi tramite


Modalità di Concorrenza Reentrant

L'esempio Reentrant illustra la necessità e le implicazioni dell'uso di ConcurrencyMode.Reentrant in un'implementazione del servizio. ConcurrencyMode.Reentrant implica che il servizio (o il callback) elabora un solo messaggio in un determinato momento (analogo a ConcurencyMode.Single). Per garantire la thread safety, Windows Communication Foundation (WCF) blocca l'elaborazione InstanceContext di un messaggio in modo che non sia possibile elaborare altri messaggi. In caso di modalità rientrante, l'oggetto InstanceContext viene sbloccato poco prima che il servizio effettui una chiamata in uscita, consentendo così alla chiamata successiva (che può essere rientrante, come illustrato nell'esempio) di ottenere il blocco al successivo ingresso nel servizio. Per illustrare il comportamento, l'esempio mostra come un client e un servizio possono inviare messaggi tra loro usando un contratto duplex.

Il contratto definito è un contratto duplex con il Ping metodo implementato dal servizio e il metodo Pong di callback implementato dal client. Un client richiama il metodo del Ping server con un conteggio dei tick avviando così la chiamata. Il servizio controlla se il conteggio dei tick non è uguale a 0 e quindi richiama il metodo di callback Pong mentre decrementa il conteggio dei tick. Questa operazione viene eseguita dal codice seguente nell'esempio.

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));
     }
}

L'implementazione del Pong callback ha la stessa logica dell'implementazione Ping . Ciò significa che controlla se il conteggio dei tick non è zero e quindi richiama il Ping metodo sul canale di callback (in questo caso, è il canale usato per inviare il messaggio originale Ping ) con il conteggio dei tick decrementato di 1. Nel momento in cui il conteggio dei tick raggiunge 0, il metodo restituisce, svelando così tutte le risposte fino alla prima chiamata effettuata dal client che ha avviato il processo. Questa operazione è illustrata nell'implementazione del callback.

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));
    }
}

Entrambi i metodi Ping e Pong sono di tipo request/reply, il che significa che la prima chiamata a Ping non restituisce fino a quando non venga restituita la chiamata a CallbackChannel<T>.Pong(). Nel client, il metodo Pong non può restituire fino a quando la chiamata successiva Ping da esso effettuata non restituisce. Poiché sia il callback che il servizio devono effettuare chiamate di richiesta/risposta in uscita prima di poter rispondere per la richiesta in sospeso, entrambe le implementazioni devono essere contrassegnate con il comportamento ConcurrencyMode.Reentrant.

Per configurare, compilare ed eseguire l'esempio

  1. Assicurati di aver eseguito la procedura di installazione di One-Time per gli esempi di Windows Communication Foundation.

  2. Per compilare l'edizione C# o Visual Basic .NET della soluzione, seguire le istruzioni in Compilazione degli esempi di Windows Communication Foundation.

  3. Per eseguire l'esempio in una configurazione con computer singolo o incrociato, seguire le istruzioni riportate in Esecuzione degli esempi di Windows Communication Foundation.

Dimostra

Per eseguire l'esempio, compilare i progetti client e server. Aprire quindi due finestre di comando e modificare le directory in <sample>\CS\Service\bin\debug e <sample>\CS\Client\bin\debug. Avviare quindi il servizio digitando service.exe e quindi richiamando il Client.exe con il valore iniziale dei tick passati come argomento di input. Viene visualizzato un output di esempio per 10 tick.

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