1. 程式人生 > 實用技巧 >WCF初探-27:WCF中的例項化

WCF初探-27:WCF中的例項化

理解WCF中的例項化機制

  • “例項化”是指對使用者定義的服務物件以及與其相關的 InstanceContext 物件的生存期的控制。也就是說我們的客戶端程式在呼叫服務端方法時,需要例項化一個服務端代理類物件,例項化就是對這個物件的生命週期的管理(比如:代理服務物件的建立,物件呼叫服務端方法後需要對其進行的回收處理)。

  

  • 例項化行為(使用 System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode 屬性進行設定)控制如何建立 InstanceContext 以響應傳入的訊息。預設情況下,每個 InstanceContext 都與一個使用者定義服務物件相關聯,因此設定 InstanceContextMode 屬性也可以控制使用者定義服務物件的例項化。InstanceContextMode 列舉定義了例項化模式。可以使用下列例項化模式:
  1. PerCall:單調模式,為每個客戶端請求建立一個新的 InstanceContext(以及相應的服務物件)。
  2. PerSession:會話模式,這是InstanceContextMode的預設值,為每個新的客戶端會話建立一個新的 InstanceContext(以及相應的服務物件),並在該會話的生存期內對其進行維護(這需要使用支援會話的繫結)。
  3. Single:單例模式,單個 InstanceContext(以及相應的服務物件)處理應用程式生存期內的所有客戶端請求。

單調模式(PerCall)下的服務例項

  • 在單調模式(PerCall)中,WCF總是建立一個新的服務例項上下文來處理請求物件,即呼叫一次方法就會建立一個例項上下文物件,呼叫完成後依靠GC機制釋放物件(可能會有延遲),再呼叫下一個方法時也會建立一個新的服務例項上下文物件。因此,在一個服務通道會話中可能出現多個例項上下文物件

  

  • 接下來我將通過示例來驗證單調模式下的例項處理請求的方式。解決方案的建立請參照WCF初探-26:WCF中的會話,此示例中,我們採用GetInstanceId()來獲取服務端例項化的次數,採用GetOperationCount()來獲取呼叫方法的計數器。ISampleMethod.cs的程式碼如下:
using System.ServiceModel;
namespace Service{
    [ServiceContract(SessionMode=SessionMode.Required)]
    public interface ISampleMethod{
        [OperationContract]
        
string MethodOne(string msg); [OperationContract] string MethodTwo(string msg); [OperationContract] int GetInstanceId(); //獲取服務例項ID [OperationContract] int GetOperationCount(); //獲取呼叫操作方法的計數器 }}

  SampleMethod.cs的程式碼如下:

using System.ServiceModel;
namespace Service{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class SampleMethod:ISampleMethod
    {
        static int instanceCount;
        int instanceId;
        int operationCount;

        public SampleMethod()
        {
           instanceCount++;
           instanceId = instanceCount;
        }

        public string MethodOne(string msg)
        {
            operationCount++;
            return "You called MethodOne return message is: " + msg;
        }

        public string MethodTwo(string msg)
        {
            operationCount++;
            return "You called MethodTwo return message is: " + msg;
        }

        public int GetInstanceId()
        {  
            return instanceId;
        }

        public int GetOperationCount()
        {   
           return operationCount;
        }
    }
}

  寄宿服務後,使用svcutil.exe生成客戶端代理類和配置檔案,客戶端參考程式碼如下:

class Program{
        static void Main(string[] args){
            SampleMethodClient client1 = new SampleMethodClient();
            CallMethod(client1);
            SampleMethodClient client2 = new SampleMethodClient();
            CallMethod(client2);
            Console.Read();
        }

        static void CallMethod(SampleMethodClient client){
            Console.WriteLine(client.MethodOne("MethodOne"));
            Console.WriteLine("InstanceId:{0},OperationCount:{1}", client.GetInstanceId(), client.GetOperationCount());
            Console.WriteLine(client.MethodTwo("MethodTwo"));
            Console.WriteLine("InstanceId:{0},OperationCount:{1}", client.GetInstanceId(), client.GetOperationCount());
        }
    }

  執行結果如下:

  

  • 執行結果說明如下:
  1. Client1呼叫MethodOne()時,會進入到SampleMethod建構函式此時instanceCount會加1,所以instanceId等於1,operationCount加1後的值為1.
  2. Client1呼叫GetInstanceId()時,會再次進入SampleMethod建構函式產生新的例項,由於instanceCount為靜態變數,所以再次加1後會變成2,所以instanceId等於2。operationCount的普通變數,所以例項化後不會記錄先前的值,呼叫GetOperationCount()時operationCount沒有加量操作。所以為預設值0.呼叫GetOperationCount()instanceId的值等於3.
  3. Client1呼叫MethodTwo()時,又會進入到SampleMethod建構函式產生新的例項,所以instanceId的值就會等於4.再次呼叫GetInstanceId()時,新的例項值又會增加1,所以客戶端最終會輸出5.而呼叫的操作計數器始終為0.
  4. 其實就是客戶端每做一次呼叫操作,SampleMethod就會被例項化一次,由此我們可以檢視到instanceId和OperationCount值的變化。

單例模式(Single)下的服務例項

  • 在單調模式(single)中,WCF只會建立一個例項上下文來處理服務的所有請求呼叫物件,即 SampleMethod只會進行一次例項化。不管呼叫的請求物件是在同一個客戶端還是在不同的客戶端。

  

  • 要檢驗單調模式(single),我們只需把服務行為的InstanceContextMode設定為single,重新編譯工程後,執行結果如下:

  

  • 執行結果說明:由於WCF採用單例模式只會生成一個例項化上下文,所以從執行的結果可以看到instanceId的值始終為1,而操作計數器OperationCount也在不斷做累加,再經過Client1和Client2呼叫處理後,在MethodOne()和MethodTwo()做累加,所以最終的值為4.

會話模式(PerSession)下的服務例項

  • 在會話模式(PerSession)中,WCF會對客戶端與服務端的每一個會話通道建立一個例項上下文。即不同的客戶端在各自的會話通道的例項上下文中處理請求物件。

  

  • 要檢驗會話模式(PerSession),我們只需把服務行為的InstanceContextMode設定為PerSession,重新編譯工程後,執行結果如下:

  

  • 執行結果說明:從執行結果可以看出客戶端例項Client1的呼叫所在的instanceId為1,操作計數器OperationCount經過兩次的呼叫(呼叫MethodOne()和MethodTwo())後做累加,最後的值為2.客戶端Client2呼叫的時候會產生新的例項上下文。所以instanceId的值為2,操作計數器OperationCount又會重新開始計數。