Sdílet prostřednictvím


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 PingPong 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

  1. Ujistěte se, že jste pro ukázky windows Communication Foundation provedli jednorázovou instalační proceduru.

  2. Pokud chcete sestavit edici C# nebo Visual Basic .NET řešení, postupujte podle pokynů v části Sestavení ukázek windows Communication Foundation.

  3. 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