共用方式為


並發模式 重新進入

Reentrant 範例示範在服務實作上使用 ConcurrencyMode.Reentrant 的必要性和含意。 ConcurrencyMode.Reentrant 表示服務(或回呼)一次只會處理一則訊息(類似於 ConcurencyMode.Single)。 為了確保線程安全性,Windows Communication Foundation (WCF)會鎖定InstanceContext處理訊息,以便其他訊息無法處理。 如果是 Reentrant 模式,InstanceContext 會在服務執行傳出呼叫之前解除鎖定,從而允許後續的呼叫在下一次進入服務時(如範例中所示,可以是重新進入)獲得鎖定。 為了展示行為,此範例示範客戶端和服務如何使用雙工合約彼此傳送訊息。

定義的合約是雙工合約,Ping 方法由服務實作,回呼方法 Pong 由用戶端實作。 用戶端會使用刻度計數叫用伺服器的 Ping 方法,藉此起始呼叫。 服務會檢查刻度計數是否不等於 0,然後在遞減刻度計數時叫用回呼 Pong 方法。 這是由範例中的下列程式代碼所完成。

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

回呼的Pong實作具有與Ping實作相同的邏輯。 也就是說,它會檢查刻度計數是否不為零,然後在回呼通道上呼叫 Ping 方法(在此情況下,這是用來傳送原始 Ping 訊息的通道),並將刻度計數減 1。 當計時器計數達到 0 時,方法會返回,並解除所有回覆,使其返回至發起呼叫的用戶端的第一次呼叫。 這會顯示於回調實現中。

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

PingPong 方法是要求/回復,這表示 第一次呼叫Ping不會傳回,直到呼叫 CallbackChannel<T>.Pong() 傳回為止。 在客戶端上,Pong 方法不能傳回,除非它進行的下一次 Ping 呼叫已傳回。 因為回呼和服務必須先發出傳出要求/回復呼叫,然後才能對待處理的要求進行回應,因此這兩個實作都必須標示為 ConcurrencyMode.Reentrant 行為。

要設定、建置和執行範例,請執行以下步驟:

  1. 請確定您已針對 Windows Communication Foundation 範例 執行One-Time 安裝程式。

  2. 若要建置解決方案的 C# 或 Visual Basic .NET 版本,請遵循建置 Windows Communication Foundation 範例 中的指示。

  3. 若要在單一或跨計算機組態中執行範例,請遵循執行 Windows Communication Foundation 範例 中的指示。

演示

若要執行範例,請建置客戶端和伺服器專案。 然後開啟兩個命令視窗,並將目錄變更為 <sample>\CS\Service\bin\debug 和 <sample>\CS\Client\bin\debug 目錄。 然後輸入 service.exe,並呼叫 Client.exe,將刻度的初始值作為輸入參數。 10個時間刻度的範例輸出已顯示。

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