Udostępnij za pośrednictwem


Procedura wielobieżna ConcurrencyMode

W przykładzie Reentrant przedstawiono konieczność i implikacje korzystania z funkcji ConcurrencyMode.Reentrant w implementacji usługi. ConcurrencyMode.Reentrant oznacza, że usługa (lub wywołanie zwrotne) przetwarza tylko jeden komunikat w danym momencie (analogiczny do ConcurencyMode.Single). Aby zapewnić bezpieczeństwo wątków, program Windows Communication Foundation (WCF) blokuje przetwarzanie komunikatu InstanceContext , aby nie można było przetworzyć żadnych innych komunikatów. W przypadku trybu InstanceContext reentrant jest odblokowywane tuż przed wykonaniem wywołania wychodzącego, dzięki czemu kolejne wywołanie (które może być ponownie możliwe, jak pokazano w przykładzie), aby uzyskać blokadę przy następnym przejściu do usługi. Aby zademonstrować zachowanie, w przykładzie pokazano, jak klient i usługa mogą wysyłać komunikaty między sobą przy użyciu kontraktu dwustronnego.

Zdefiniowany kontrakt jest kontraktem dwudupleksowym z Ping metodą zaimplementowaną przez usługę i metodą Pong wywołania zwrotnego implementowanych przez klienta. Klient wywołuje metodę serwera Ping z liczbą znaczników, inicjując wywołanie. Usługa sprawdza, czy liczba znaczników nie jest równa 0, a następnie wywołuje metodę wywołań zwrotnych Pong podczas dekrementacji liczby znaczników. Jest to wykonywane za pomocą następującego kodu w przykładzie.

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

Implementacja Pong wywołania zwrotnego ma taką samą logikę jak implementacja Ping . Oznacza to, że sprawdza, czy liczba znaczników nie jest równa zero, a następnie wywołuje Ping metodę w kanale wywołania zwrotnego (w tym przypadku jest to kanał, który został użyty do wysłania oryginalnego Ping komunikatu) z liczbą znaczników zdekrementowaną przez 1. Gdy liczba znaczników osiągnie wartość 0, metoda zwraca w ten sposób rozpasanie wszystkich odpowiedzi z powrotem do pierwszego wywołania wykonanego przez klienta, który zainicjował wywołanie. Jest to wyświetlane w implementacji wywołania zwrotnego.

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

Metody i Pong to żądanie/odpowiedź, co oznacza, że pierwsze wywołanie metody nie zwraca się do momentu zwrócenia wywołania CallbackChannel<T>.Pong()Ping .Ping Na kliencie Pong metoda nie może powrócić do momentu następnego Ping wywołania, które dokonało zwrotów. Ponieważ zarówno wywołanie zwrotne, jak i usługa musi wysyłać wychodzące żądania/wywołania odpowiedzi, zanim będą mogły odpowiedzieć na oczekujące żądanie, obie implementacje muszą być oznaczone zachowaniem ConcurrencyMode.Reentrant.

Aby skonfigurować, skompilować i uruchomić przykład

  1. Upewnij się, że wykonano procedurę instalacji jednorazowej dla przykładów programu Windows Communication Foundation.

  2. Aby skompilować wersję rozwiązania w języku C# lub Visual Basic .NET, postępuj zgodnie z instrukcjami w temacie Building the Windows Communication Foundation Samples (Tworzenie przykładów programu Windows Communication Foundation).

  3. Aby uruchomić przykład w konfiguracji pojedynczej lub między maszynami, postępuj zgodnie z instrukcjami w temacie Uruchamianie przykładów programu Windows Communication Foundation.

Demonstracje

Aby uruchomić przykład, skompiluj projekty klienta i serwera. Następnie otwórz dwa okna poleceń i zmień katalogi na <sample>\CS\Service\bin\debug i <sample>\CS\Client\bin\debug. Następnie uruchom usługę, wpisując service.exe , a następnie wywołaj Client.exe z początkową wartością znaczników przekazanych jako argument wejściowy. Wyświetlane są przykładowe dane wyjściowe dla 10 znaczników.

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