單例模式 (InstanceContextMode.Single) 下,WCF 僅建立唯一服務實例處理所有客戶端請求,狀態為所有客戶端共享。本文示範單一性驗證、已知單例與隱式單例、單例實例上下文建立機制,並探討並發模式對擴展性的影響。
累加器服務:Add 累加、GetResult 取值。兩個代理分別呼叫 Add(3),第二個代理取得結果為 6,證實共享同一實例。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class CalculatorService : ICalculator
{
private double _result;
public void Add(double x) { this._result += x; }
public double GetResult() { return this._result; }
}
new ServiceHost(singletonInstance, baseAddresses) 寄宿。可從 ServiceHost.SingletonInstance 或 OperationContext.Current.Host 取得。ServiceHost 初始化階段透過無參建構函式建立,儲存於 ServiceBehaviorAttribute.hiddenSingleton。發生於 ServiceHost.Open() 期間的「應用分發行為」步驟。ServiceBehaviorAttribute.ApplyDispatchBehavior 依據是否有已知單例,決定以哪個實例建立 SingletonInstanceContext,並設定至 DispatchRuntime.SingletonInstanceContext。因 DispatchRuntime 生命週期等同 ServiceHost,故達成真正單例。
預設並發模式 ConcurrencyMode.Single 導致多線程同步存取單一實例,嚴重限制吞吐量。測試 5 併發請求,每請求耗時 5 秒:
PerCall 模式:約 5 秒完成所有請求。Single + ConcurrencyMode.Single:串行執行,耗時 25 秒。Single + ConcurrencyMode.Multiple:並行執行,約 5 秒完成,但需自行處理狀態同步(如加鎖)。ConcurrencyMode 可透過 [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 設定。選擇 Multiple 時,開發者須確保執行緒安全。