在 WCF 架構中,服務調用的最終目的在於消費特定的服務功能,而這些功能的實現邏輯封裝於服務類型之中。無論 WCF 服務端框架處理請求的流程多麼複雜,核心都落腳於服務實例的激活與操作方法的執行。WCF 的實例管理機制專門解決服務實例的建立、存活與銷毀,即生命週期控制問題。
會話的引入旨在維持來自同一客戶端(服務代理)多次調用之間的狀態。從訊息交換角度看,會話透過訊息識別機制判斷訊息來源,將同一客戶端的所有訊息關聯起來,實現了訊息關聯。實例與會話是 WCF 兩大核心特性,它們相互獨立又相互制約。實例模式與會話支援程度的不同組合,會造就截然不同的服務行為。合理運用實例管理與會話,對提升 WCF 應用的擴展性、效能與吞吐量具有決定性影響。
服務實例物件並非孤立存在,而是被封裝在一個特殊的 實例上下文 物件中。本文將從實例上下文切入,深入剖析 WCF 服務實例的生命週期控制機制。
實例上下文是對服務實例的封裝,也是 WCF 管理服務實例生命週期的基石。為了理解其角色,我們先回顧 CLR 如何管理託管物件的生命週期。在託管環境中,物件建立時 CLR 會在託管堆分配記憶體,物件的生命週期終結於記憶體被垃圾收集器回收之時。GC 透過判斷物件是否被「根」引用來決定其存亡。孤立物件難逃被回收命運,若想讓物件常駐記憶體,必須讓某個「根」持續引用它。
實例管理的本質,就是控制服務實例何時被「根」引用、何時釋放引用。InstanceContext 正是扮演這個「根」的關鍵角色。它不僅用於雙向通信中的回呼物件封裝,更是服務實例生命週期的核心控制點。通信雙方在雙向通信中地位對等,服務端回呼客戶端操作同樣可視為一種服務調用,因此回呼物件與服務實例的封裝本質一致。

圖 1 實例上下文對服務實例的封裝
一個 WCF 服務透過 ServiceHost 寄宿,包含一或多個端點。當接收到調用請求,若對應的 InstanceContext 已存在,則直接獲取其中的服務實例處理;否則建立新實例並封裝進 InstanceContext 再行處理。
System.ServiceModel.InstanceContext 繼承自 CommunicationObject,實作 IExtensibleObject<InstanceContext>。其核心成員如下:
public sealed class InstanceContext : CommunicationObject, IExtensibleObject<InstanceContext>
{
// 建構函式
public InstanceContext(object implementation);
public InstanceContext(ServiceHostBase host);
public InstanceContext(ServiceHostBase host, object implementation);
// 實例存取
public object GetServiceInstance();
public object GetServiceInstance(Message message);
public void ReleaseServiceInstance();
// 屬性
public IExtensionCollection<InstanceContext> Extensions { get; }
public ServiceHostBase Host { get; }
public ICollection<IChannel> IncomingChannels { get; }
public ICollection<IChannel> OutgoingChannels { get; }
public SynchronizationContext SynchronizationContext { get; set; }
}
三個建構函式分別接受服務宿主與實例物件。GetServiceInstance 與 ReleaseServiceInstance 用於實例的獲取與釋放。IncomingChannels/OutgoingChannels 代表輸入/輸出通道集合。SynchronizationContext 允許設定非同步操作的同步上下文(例如在非 UI 執行緒操作 Windows Forms 控制項時)。
實例上下文模式定義了服務端實例與客戶端代理的綁定方式。這與 .NET Remoting 的遠端物件激活模式(SAO/CAO)高度相似,分為三種:
對應 .NET Remoting 的 SingleCall。每次服務調用(無論來自同一或不同客戶端),WCF 都會建立全新的服務實例與 InstanceContext,操作完成後立即回收。這是無狀態、高擴展性的模式。

圖 2 單調模式下服務代理與服務實例上下文關聯
對應 .NET Remoting 的 CAO。WCF 為每個服務代理分配專屬的 InstanceContext,同一代理的所有調用分發給同一實例,實現狀態保持。這是預設模式。

圖 3 會話模式下服務代理與服務實例上下文關聯
對應 .NET Remoting 的 Singleton。整個服務僅維護一個 InstanceContext,所有客戶端共享同一實例。適合全域狀態共享場景,但需注意併發與擴展性限制。

圖 4 單例模式下服務代理與服務實例上下文關聯
WCF 中契約描述雙邊交互,行為描述單邊實現。客戶端不關心服務端如何激活實例,因此實例管理屬於服務行為,透過 ServiceBehaviorAttribute 的 InstanceContextMode 屬性指定:
[AttributeUsage(AttributeTargets.Class)]
public sealed class ServiceBehaviorAttribute : Attribute, IServiceBehavior
{
public InstanceContextMode InstanceContextMode { get; set; }
}
public enum InstanceContextMode
{
PerCall,
PerSession, // 預設值
Single
}
後續文章將逐一剖析各模式的實現原理,助您透徹掌握 WCF 服務物件生命週期管理機制。