WCF 服務與用戶端間維持何種執行個體關係,直接影響狀態管理、擴展性與效能。透過 ServiceBehaviorAttribute.InstanceContextMode 可選擇三種模式:
InstanceContextMode.PerCall)。InstanceContextMode.PerSession)。InstanceContextMode.Single)。定義服務介面 IMyContract 與實作 MyContract,含 Count() 方法累加計數器並輸出追蹤。用戶端連續呼叫三次 Count() 觀察輸出:
[ServiceContract]
public interface IMyContract {
[OperationContract] void Count();
}
// Per-Call
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class MyContract : IMyContract, IDisposable {
int count = 0;
public void Count() { count++; Trace.WriteLine("Counter = " + count); }
public MyContract() { Trace.WriteLine("MyContract()"); }
public void Dispose() { Trace.WriteLine("Dispose()"); }
}
MyContract()
Counter = 1
Dispose()
MyContract()
Counter = 1
Dispose()
MyContract()
Counter = 1
Dispose()
每次呼叫皆為新執行個體,計數器歸零。
將屬性改為 PerSession:
MyContract()
Counter = 1
Counter = 2
Counter = 3
Dispose()
同一 Proxy 內共用執行個體,計數器累加。注意:若繫結不支援 Session (如 basicHttpBinding),行為退化為 Per-Call。
wsHttpBinding 預設支援可靠 Session。basicHttpBinding 無 Session 支援,每個 HTTP 請求視為新連線。[ServiceContract(SessionMode=SessionMode.Required)] 強制要求 Session,不支援時拋出例外。SessionMode.Allowed (預設):繫結支援則用 Session,否則退回 Per-Call。SessionMode.NotAllowed:禁止 Session,建議搭配 Per-Call 使用。inactivityTimeout 決定閒置多久回收執行個體;AutomaticSessionShutdown 控制 proxy.Close() 是否立即結束 Session。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]:
Dispose() 僅在 Host 關閉時觸發。ConcurrencyMode.Single 導致同一時間僅處理一個訊息,高併發需設定 ConcurrencyMode.Multiple。兩種方式注入預建立執行個體:
MyContract singleInstance = new MyContract();
singleInstance.CountProperty = 200; // 設定初始狀態
ServiceHost host = new ServiceHost(singleInstance);
host.AddServiceEndpoint(...);
host.Open();
呼叫過程中可直接修改 singleInstance.CountProperty,服務端即時生效。OperationContext.Current.Host.SingletonInstance 取得:需在服務方法內執行,確保 OperationContext 已初始化。Console 應用程式自架服務測試時,OperationContext.Current 可能為 null,需在真實 IIS/WAS 或 Self-Host 服務方法中驗證。Singleton 適合共用快取、狀態協調等場景,但需自行處理執行緒安全與併發控制。