Step by Step WCF—Instance Management

來源:互聯網
上載者:User

在本次實驗中你將會體會到三種不同的執行個體管理員模式。開啟Instance Management檔案夾下的InstanceManagement.sln解決方案。解決方案中包含了一個簡單的伺服器端和用戶端。它們都被配置為了BasicHttpBinding。

<services>
 <service name = "MyNamespace.MyService">
 <endpoint
    address  = "http://localhost:8000/MyService" 
    binding  = "basicHttpBinding"
    contract = "MyNamespace.IMyContract" 
 />
 </service>

為了監視執行個體的建立、回收和狀態,service端的代碼在它的三個方法:建構函式、MyMethod()和Dispose()中都會顯示一個MessageBox來表明狀態。另外service中有一個m_Counter的int型欄位,我們可以通過觀察它來得知我們是不是獲得了一個新的執行個體。

[ServiceContract]
interface IMyContract
{
  [OperationContract]
  void MyMethod();
}
class MyService : IMyContract,IDisposable
{
  int m_Counter = 0;
  public MyService()
  {
  MessageBox.Show("Counter = " + m_Counter,"MyService.MyService()");
  }
  public void MyMethod()
  {
  m_Counter++;
  MessageBox.Show("Counter = " + m_Counter,"MyService.MyMethod()");

  string sessionID = OperationContext.Current.SessionId;
  Trace.WriteLine("Service Session ID: " + (sessionID??"None"));
  }
  public void Dispose()
  {
  MessageBox.Show("","MyService.Dispose()");
  }
}

MyMethod方法同樣還記錄了session ID。

Client端的代碼建立了一個代理來調用MyMethod()方法:

void OnCall(object sender,EventArgs e)
{
 MyContractClient proxy = new MyContractClient();

 proxy.MyMethod();
 proxy.MyMethod();

 IContextChannel channel = proxy.InnerChannel;
 string sessionID = channel.SessionId;
 Trace.WriteLine("Client Session ID: " + (sessionID??"None"));

 proxy.Close();
}

Client端同樣記錄了session ID。編譯並運行程式。

Per-Call模式
Per-Call意味著對於兩次client端的調用,你將會得到兩個不同的執行個體。也就是說即使client端兩次調用使用的是相同的代理,每一次調用伺服器端執行個體建構函式都會被調用一次。m_Counter的值始終都是1。在函數返回後Dispose()方法都會在後台被執行。注意到,在Debug視窗中我們可以觀察到session ID都是沒有的。
我們也可以顯示的將服務配置為Per-Call類型。只需要將InstanceContextMode屬性設定為InstanceContextMode.PerCall即可:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class MyService : IMyContract, IDisposable
{……}

Per-Session模式
接下來,我們將會把服務配置為每個用戶端都會關聯到一個特定的服務,類似於經典的C/S模式。將伺服器屬性InstanceContextMode修改為InstanceContextMode.PerSession:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract, IDisposable
{……}

你會看到,服務仍然是Per-Call的,並沒有session。因為要將session設定為contract的一部分,這樣才會有效果。開啟MyService.cs檔案,將service contract的SessionMode屬性設定為

SessionMode.Required:
[ServiceContract(SessionMode = SessionMode.Required)]
interface IMyContract
{……}

同樣,在client端的Proxy.cs檔案中也需要做這樣的定義。
編譯器並運行,你會得到如下的異常:
 
這是因為BasicHttpBinding不支援session。開啟app.config檔案,將binding改為WSHttpBinding:

 <service name = "MyNamespace.MyService">
    <endpoint
       address  = "http://localhost:8000/MyService" 
       binding  = "wsHttpBinding"
       contract = "MyNamespace.IMyContract" 
    />
 </service>

在client端也做同樣的設定。
編譯後運行程式。這一次你將只會得到一個伺服器執行個體,counter的數量會變為2,執行個體也僅僅是在client端關閉後調用一次。啟動兩個client程式觀察一下呢?

單一實例模式
第三種是單一實例模式(Singleton),即所有client端都串連到同一個執行個體上。將伺服器屬性InstanceContextMode修改為InstanceContextMode.Single:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MyService : IMyContract, IDisposable
{……}

編譯並運行程式,你將會看到,在沒有任何client調用的時候伺服器端的建構函式已經執行了。點擊client端的button兩次,counter的數量應該為4。關閉client程式,Dispose方法仍然沒有被調用。
單一實例模式是不需要session的,將SessionMode=SessionMode.Required去掉再試試看呢。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.