WCF開發時如何選擇正確的實例模式(InstanceMode)?


在使用WCF實例模型時,你是否思考過這幾個的問題:
  • ”WCF中的實例模式如何正確應用”?
  • ”使用WCF中的實例模式有何原則可以遵循嗎”? 


眾所周知:客戶端調用服務時,最終會將調用服務端的某個實例來完成。在WCF服務中,可以通過ServiceBehavior的InstanceContextMode設置服務實例。

InstanceContextMode定義如下:

  //  摘要:
    
//      指定可用來處理包含在傳入消息中的調用的服務實例數。
     public  enum InstanceContextMode
    {
         //  摘要:
        
//      為每個會話創建一個新的 System.ServiceModel.InstanceContext 對象。
        PerSession =  0,
         //
        
//  摘要:
        
//      新的 System.ServiceModel.InstanceContext 對象在每次調用前創建,在調用后回收。如果信道未創建會話,則該值的行為就如同
        
//      System.ServiceModel.InstanceContextMode.PerCall 一樣。
        PerCall =  1,
         //
        
//  摘要:
        
//      只有一個 System.ServiceModel.InstanceContext 對象用於所有傳入呼叫,並且在調用后不回收。如果服務對象不存在,則創建一個。
        Single =  2, } 

既然InstanceContextMode有三個枚舉值,那就說明WCF服務端的實例有三種表現形式。那在平時的開發過程中,我們應遵循什么樣的原則來采用哪種實例模式。? 

首先看看在三種實例模式下,服務端實例具有怎樣的表現。 

服務實現:在服務的構造函數中,初始化計數器,進行服務調用時,將計數器進行累加輸出。如下:

private  int  _counter;
public AddService()
{
    _counter =  0;
    Console.WriteLine( " Single Mode ");
}

public  int Add( int x,  int y)
{
     Console.WriteLine( " Start invoke... ");
     Console.WriteLine( " Invoke Thread Id is {0} ", System.Threading.Thread.CurrentThread.ManagedThreadId);           
     _counter++;
     Console.WriteLine( " counter is :{0} ", _counter);
      return x + y;
}


 

1、各種實例模式的表現 

PerCall模式

客戶端調用時,服務端輸出如下:

 

可以看出:PerCall 模式下,每次進行服務調用,實例都會進行初始化,並且實例銷毀與服務調用是同一個線程完成的。 

PerSession模式 

客戶端調用時,服務端輸出如下:

 

 可以看出:PerSession模式下,每次進行服務調用,實例都會進行初始化,但是對與每個代理,服務會使用同一個實例對象來為客戶端服務。注意:同一客戶端值的是同一個代理對象(透明代理),而不是計算機

使用會話模式有三個要求:1、使用支持會話的綁定 ;2、契約為會話契約;3、實例模式為:PerSession

Single模式  

客戶端調用時,服務端輸出如下:

        

 可以看出:Single模式下,所有客戶端共享同一個服務實例對象。
 

 2、如何選擇服務實例模型

 要選擇服務實例模型,首先看看這三種模型各有什么優缺點:

PerCall: 

優點:對於客戶端調用來說,服務不用每次為服務的調用進行狀態的同步,因為每次進行服務調用都會要求服務重新進行資源分配;能夠對客戶端的並發調用即使響應。只有在並發調用的時候,服務端才會在內存中創建和維護多個服務實例。在進行服務調用時,客戶端僅僅持有服務的代理,而不會占用實際的資源,只有在發生服務調用時,才會獲取資源。

缺點:對並行的調用需要自己進行線程同步;由於每次調用都需要重建資源的狀態,對性能有一定的影響。 

PerCall模式下,即使不停的創建於銷毀服務實例,也不會釋放與客戶端的連接。因為建立連接遠比服務實例的創建於銷毀所需資源要多的多。

 

PerSession:

 

優點:服務端能識別不同的客戶端代理,能為相同的客戶端分配同一個實例,這個實例對象會一直保持,直到會話的結束。

缺點:整個會話期間,占用服務器資源,因此無法支持過多的客戶端,因為創建服務實例代價比較大;與客戶端、服務器模式一樣存在可伸縮性的問題。

維持服務端與客戶端的會話,WCF依靠傳輸層會話或者通過ws*綁定來模擬傳輸層會話。

 

 

    Single:

優點:無需考慮線程的同步問題,客戶端對服務的調用是排隊進行的,服務一次只能為一個客戶端進行處理,處理完成后才能進行為下一個客戶端服務。

缺點:由於是串行的方式為客戶端服務,所以效率比較低。服務的可伸縮性限制比較大

 

3、設計服務 

3.1、PerCall模式

設計單調服務(PerCall模式時):雖然可以應用在任一服務上,但是在設計此類服務時還是應該注意到一些問題:由於客戶端不用關心服務端實例模型,PerCall模式下,服務也是每次都為客戶端端的調用分配新的實例對象,調用完成后就銷毀實例,因此客戶端需要進行一些狀態管理。 為此,客戶端在進行服務調用時,服務端實例對象實例化時需要從存儲介質中獲取狀態,那么每個操作對都應該有只是一個參數,在進行服務調用時,通過參數來初始化狀態。

示例:

 

      [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]

    publicclass OrderService : IOrder,IDisposable

    {
        private int _counter;

        public OrderService()
        {
            _counter = 0;
            Console.WriteLine("perCall Mode");
            Console.WriteLine("counter is {0}", _counter);
        }

        #region IOrder Members

        public void Order(string orderId)
        {                       
            int amount = GetStore(orderId);
            UpdateStore(amount - order.Number);
        }

        #endregion

        private int GetStore(string orderId)
        {
            string connectionString = ConfigurationManager.AppSettings["connectionString"];
            using (var connection = new SqlConnection(connectionString))
            {
                connection.Open();
                 //獲取庫存數量信息
                return int;
            }
        }

        private void UpdateStore(int p)
        {
            string connectionString = ConfigurationManager.AppSettings["connectionString"];
            using (var connection = new SqlConnection(connectionString))
            {
                connection.Open();
                // 將庫存信息更新到數據庫                
            }
        }


        public void Dispose()
        {
            //釋放資源
        }
    }

 

  3.2、PerSession模式

使用PreSession模式時,即使WCF在一個服務實現中,將服務實現的多個契約定義為會話或者非會話模式,但最好使用一致性配置,即所有契約都支持會話,避免將不同模式的服務定義在一個服務實現中。 

3.3、Single模式 

Single模式的服務於可伸縮性有着劇烈的沖突。Single模式的服務所有的客戶端代理均使用同一個服務實例,WCF服務保證了服務狀態的同步性。存在並發性訪問比較高的情況下,它帶來的是性能的嚴重下降。 只有在應用場景中適用單例的時候使用它。通常,應盡可能的使用其他方案來使狀態同步,盡量避免使用Single模式.

后記:讀《WCF 服務編程》后的對實例模式的重新認識。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM