首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 實戰 (8):Session 與 Instance Management 深度解析 — PerCall、PerSession、Singleton 全場景實測

     編輯:關於.NET

一、WCF Session 本質

WCF Session 將相關訊息交換歸入同一 Conversation,以 SessionId 識別。與 ASP.NET Session 差異巨大:

特性WCF SessionASP.NET Session
初始化發起方Client (Proxy 建立/呼叫)Server
狀態儲存不儲存狀態資料,靠 Instance Context 綁定Server 端 (InProc/StateServer/SQL)
訊息順序保證是否
終止方式Proxy.Close() 或標註 IsTerminating OperationTimeout / Abandon

二、Instance Context Mode 決定 Session 行為

三種模式對應不同的 Proxy-Service Instance 對應關係:

  • PerCall:每次呼叫建立新 Instance,呼叫結束回收。相當於無 Session 行為。
  • PerSession (預設):同一 Session (同一 Proxy) 共享單一 Instance,Session 結束回收。
  • Singleton:Host 啟動時即建立單一 Instance,所有 Client 共享。

三、完整實測範例 (Calculator 累加器)

Service Contract

[ServiceContract]
public interface ICalculator
{
    [OperationContract(IsOneWay=true)] void Adds(double x);
    [OperationContract] double GetResult();
}

Service 實作 (含建構子/解構子追蹤)

public class CalculatorService : ICalculator
{
    private double _result;
    public CalculatorService() => Console.WriteLine("Instance Created");
    ~CalculatorService() => Console.WriteLine("Instance Destroyed");

    public void Adds(double x) { _result += x; Console.WriteLine($"Session: {OperationContext.Current.SessionId}"); }
    public double GetResult() => _result;
}

四、場景實測結果

1. basicHttpBinding (不支援 Session) → 實際為 PerCall

兩次 Proxy 呼叫 Adds(1), Adds(2) 結果皆為 0。Host 輸出顯示每呼叫建立/銷毀一次 Instance,SessionId 為 null。

Client 結果 Host Instance 建構/解構

2. wsHttpBinding (支援 Session) + 預設 PerSession

Proxy1 累加 1+2=3,Proxy2 另起爐灶 1+2=3。Host 只建立兩個 Instance,無解構輸出 (Proxy 未 Close)。

Client 累加結果 Host 兩個 Instance 存活

3. 明確關閉 Proxy → Instance 回收

(proxy as ICommunicationObject).Close(); // 觸發解構子

Host 出現 "Instance Destroyed" 輸出。

4. ServiceContract 禁用 Session (SessionMode.NotAllowed) → 強制 PerCall

即使 Binding 支援 Session,結果同 basicHttpBinding。

5. 自訂 Session 生命週期 (IsInitiating/IsTerminating)

[OperationContract(IsInitiating=true, IsTerminating=false)] void Adds(double x);
[OperationContract(IsInitiating=false, IsTerminating=true)] double GetResult();

呼叫 GetResult() 後 Session 終止,同一 Proxy 再呼叫 Adds() 拋出例外。

6. 服務端強制指定 InstanceContextMode

  • [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]:即使 Contract 允許 Session,行為仍為 PerCall。
  • InstanceContextMode.Single:Host 啟動即建立 Instance,所有 Proxy 共享狀態 (Proxy2 結果為 6)。

Singleton Host 啟動即建立 Singleton 共享狀態結果

五、總結

  1. Session 支援需 Binding 允許 + Contract 允許 + InstanceContextMode 不為 PerCall。
  2. PerSession 是預設且最常用模式,對應「一個 Proxy 一個 Instance」。
  3. Singleton 適用於共享狀態、快取、單例資源;需注意併發 (ConcurrencyMode) 設定。
  4. 明確控制 Session 生命週期請使用 IsInitiating/IsTerminating。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved