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 Ping
Pong
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
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.
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.
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