Megosztás a következőn keresztül:


ConcurrencyMode Reentrant

A Reentrant-minta bemutatja a ConcurrencyMode.Reentrant szolgáltatás-implementációra való használatának szükségességét és következményeit. A ConcurrencyMode.Reentrant azt jelenti, hogy a szolgáltatás (vagy a visszahívás) csak egy üzenetet dolgoz fel egy adott időpontban (ehhez hasonlóan ConcurencyMode.Single). A szálbiztonság érdekében a Windows Communication Foundation (WCF) zárolja az InstanceContext üzenetek feldolgozását, hogy ne lehessen más üzeneteket feldolgozni. Reentrant mód esetén a InstanceContext zárolás közvetlenül azelőtt van feloldva, hogy a szolgáltatás kimenő hívást kezdeményezne, így a következő hívás (amely a mintában bemutatott módon újra meghívható) lehetővé teszi a zárolás lekérését, amikor legközelebb beérkezik a szolgáltatásba. A viselkedés szemléltetéséhez a minta bemutatja, hogy az ügyfél és a szolgáltatás hogyan küldhet üzeneteket egymás között kétoldalas szerződéssel.

A definiált szerződés kétoldalas szerződés, Ping amely a szolgáltatás által implementált metódust és az ügyfél által implementált visszahívási metódust Pong követi. Az ügyfél egy osztásszámmal hívja meg a kiszolgáló metódusát Ping , és ezzel elindítja a hívást. A szolgáltatás ellenőrzi, hogy az osztásszám nem egyenlő-e 0-tal, majd meghívja a visszahívási Pong metódust, miközben csökken a kullancsok száma. Ezt a mintában szereplő alábbi kód végzi.

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

A visszahívás implementációja Pong ugyanazzal a logikával rendelkezik, mint az Ping implementáció. Ez azt jelenti, hogy ellenőrzi, hogy az osztásszám nem nulla-e, majd meghívja a Ping metódust a visszahívási csatornán (ebben az esetben az eredeti Ping üzenet küldéséhez használt csatorna), és az 1-zel csökkent tick darabszámmal. Abban a pillanatban, amikor a kullancsok száma eléri a 0-t, a metódus visszatér, így az összes válasz visszakerül a hívást kezdeményező ügyfél által kezdeményezett első hívásra. Ez a visszahívási implementációban jelenik meg.

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

Mind a PingPong metódusok a kérés/válasz, ami azt jelenti, hogy az első hívás Ping nem tér vissza, amíg a hívás CallbackChannel<T>.Pong() vissza nem tér. Az ügyfélen a Pong metódus csak a következő Ping hívás után térhet vissza. Mivel mind a visszahívásnak, mind a szolgáltatásnak kimenő kéréseket/válaszhívásokat kell kezdeményeznie, mielőtt válaszolhatnak a függőben lévő kérésre, mindkét implementációt meg kell jelölni a ConcurrencyMode.Reentrant viselkedéssel.

A minta beállítása, összeállítása és futtatása

  1. Győződjön meg arról, hogy elvégezte a Windows Communication Foundation-minták egyszeri beállítási eljárását.

  2. A megoldás C# vagy Visual Basic .NET kiadásának létrehozásához kövesse a Windows Communication Foundation-minták készítéséhez szükséges utasításokat.

  3. Ha a mintát egy vagy több gép közötti konfigurációban szeretné futtatni, kövesse a Windows Communication Foundation-minták futtatásával kapcsolatos utasításokat.

Bemutatja

A minta futtatásához hozza létre az ügyfél- és kiszolgálóprojekteket. Ezután nyisson meg két parancsablakot, és módosítsa a könyvtárakat a <minta>\CS\Service\bin\debug és <sample>\CS\Client\bin\debug könyvtárakra. Ezután indítsa el a szolgáltatást gépeléssel service.exe , majd hívja meg a Client.exe a bemeneti argumentumként átadott kullancsok kezdeti értékével. 10 pipa mintakimenete jelenik meg.

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