ConcurrencyMode Reentrant
Ukázka Reentrant ukazuje nutnost a důsledky použití ConcurrencyMode.Reentrant na implementaci služby. ConcurrencyMode.Reentrant znamená, že služba (nebo zpětné volání) zpracovává pouze jednu zprávu v daném okamžiku (podobně jako ConcurencyMode.Single
). Aby bylo zajištěno zabezpečení vláken, technologie Windows Communication Foundation (WCF) uzamkne InstanceContext
zpracování zprávy, aby se nezpracovály žádné jiné zprávy. V případě režimu Reentrant je odemknuté těsně před tím, InstanceContext
než služba provede odchozí volání, což umožní následné volání (což může být znovu prokázáno v ukázce) získat zámek při příštím doručení do služby. Abychom si ukázali chování, ukázka ukazuje, jak klient a služba můžou posílat zprávy mezi sebou pomocí duplexního kontraktu.
Kontrakt definovaný je duplexní kontrakt s metodou Ping
implementovanou službou a metodou Pong
zpětného volání implementovanou klientem. Klient vyvolá metodu serveru Ping
s počtem záškrtů, čímž zahájí volání. Služba zkontroluje, jestli se počet záčtů nerovná 0, a pak vyvolá metodu zpětného Pong
volání při dekrementování počtu záčtů. To se provádí pomocí následujícího kódu v ukázce.
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));
}
}
Implementace zpětného Pong
volání má stejnou logiku jako implementace Ping
. To znamená, že zkontroluje, zda počet záškrtů není nula, a pak vyvolá Ping
metodu v kanálu zpětného volání (v tomto případě se jedná o kanál, který byl použit k odeslání původní Ping
zprávy) s dekrementovaným počtem záškrtů o 1. V okamžiku, kdy počet záškrtů dosáhne hodnoty 0, metoda se vrátí a tím zruší všechny odpovědi zpět na první volání provedené klientem, který hovor zahájil. To se zobrazí v implementaci zpětného volání.
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));
}
}
Obě metody Ping
Pong
jsou požadavek/odpověď, což znamená, že první volání Ping
se nevrátí, dokud se volání CallbackChannel<T>.Pong()
nevrátí. V klientovi se Pong
metoda nemůže vrátit, dokud další Ping
volání, které provedlo vrácení. Vzhledem k tomu, že zpětné volání i služba musí před odpověďmi na čekající požadavek provádět odchozí volání nebo volání odpovědí, musí být obě implementace označené chováním ConcurrencyMode.Reentrant.
Nastavení, sestavení a spuštění ukázky
Ujistěte se, že jste pro ukázky windows Communication Foundation provedli jednorázovou instalační proceduru.
Pokud chcete sestavit edici C# nebo Visual Basic .NET řešení, postupujte podle pokynů v části Sestavení ukázek windows Communication Foundation.
Pokud chcete spustit ukázku v konfiguraci s jedním nebo více počítači, postupujte podle pokynů v části Spuštění ukázek windows Communication Foundation.
Demonstruje
Pokud chcete ukázku spustit, sestavte projekty klienta a serveru. Pak otevřete dvě okna příkazů a změňte adresáře na <sample>\CS\Service\bin\debug a <sample>\CS\Client\bin\debug adresáře. Pak službu spusťte zadáním service.exe
a vyvoláním Client.exe s počáteční hodnotou záškrtů předaných jako vstupní argument. Zobrazí se ukázkový výstup pro 10 tis.
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