服務(wù)調(diào)用的目的體現(xiàn)在對(duì)某項(xiàng)服務(wù)功能的消費(fèi)上,而功能的實(shí)現(xiàn)又定義在相應(yīng)的服務(wù)類型中。不論WCF服務(wù)端框架處理服務(wù)調(diào)用請(qǐng)求的流程有多么復(fù)雜,最終都落實(shí)在服務(wù)實(shí)例的激活和操作方法的執(zhí)行上面。WCF中的實(shí)例管理(Instance Management)旨在解決服務(wù)實(shí)例的激活和服務(wù)實(shí)例生命周期的控制。
會(huì)話(Session)的目的在于保持來自相同客戶端(服務(wù)代理)多次服務(wù)調(diào)用之間的狀態(tài)。從消息交換的角度來講,會(huì)話通過消息識(shí)別機(jī)制判斷調(diào)用某個(gè)服務(wù)的消息來源,從而將來自相同客戶端的所有消息關(guān)聯(lián)在一起。所以,會(huì)話實(shí)現(xiàn)了消息關(guān)聯(lián)(Message Correlation)。
實(shí)例與會(huì)話是WCF非常重要的兩個(gè)特性,它們既相對(duì)獨(dú)立,又互相制約。實(shí)例模式與對(duì)會(huì)話支持程度的不同組合,會(huì)讓最終的服務(wù)表現(xiàn)出截然不同的行為。對(duì)實(shí)例管理和會(huì)話的合理利用,對(duì)于改善和提高WCF服務(wù)應(yīng)用的可擴(kuò)展性(Scalability)、性能(Performance)、吞吐量(Throughput)等具有決定性作用。服務(wù)實(shí)例對(duì)象并不是孤立存在的,而是被封裝到一個(gè)特殊實(shí)例上下文(InstanceContext)對(duì)象之中,本系列文章從實(shí)例上下文說起。
一、實(shí)例上下文(InstanceContext)
實(shí)例上下文是對(duì)服務(wù)實(shí)例的封裝,是WCF管理服務(wù)實(shí)例生命周期的依托。我們先撇開WCF,來簡(jiǎn)單介紹一下在托管的環(huán)境中,公共語(yǔ)言運(yùn)行時(shí)(CLR)是如何進(jìn)行托管對(duì)象的生命周期的。在一個(gè)托管應(yīng)用程序中,我們通過不同的方式創(chuàng)建一個(gè)托管對(duì)象(比如通過new關(guān)鍵字、反射或反序列化等)時(shí),CLR會(huì)在托管堆為該對(duì)象開辟一塊內(nèi)存空間。對(duì)象的本質(zhì)就是存儲(chǔ)于某塊內(nèi)存中數(shù)據(jù)的體現(xiàn),對(duì)象的生命周期終止于相應(yīng)內(nèi)存被回收之時(shí)。對(duì)于CLR來說,負(fù)責(zé)對(duì)托管堆(在這里主要指GC堆)進(jìn)行回收的組件是垃圾收集器(GC),GC掌握著托管對(duì)象的生殺大權(quán),決定著托管對(duì)象的生命周期。
當(dāng)GC在進(jìn)行垃圾回收的時(shí)候,會(huì)將“無用”的對(duì)象標(biāo)記為垃圾對(duì)象,然后再對(duì)垃圾對(duì)象進(jìn)行清理。GC對(duì)“無用”對(duì)象的識(shí)別機(jī)制很簡(jiǎn)單:判斷對(duì)象是否被“根(Root)”所引用。在這里,“根”是對(duì)一組當(dāng)前正被使用,或者以后可能被使用的對(duì)象的統(tǒng)稱,大體包括這樣的對(duì)象:類型的靜態(tài)字段或當(dāng)前的方法參數(shù)和局部變量、CPU寄存器等。
所以,孤立存在的對(duì)象將難逃被GC回收的厄運(yùn)。反之,如果希望某個(gè)對(duì)象常駐內(nèi)存中,我們唯一的方式就是通過某個(gè)“根”引用該對(duì)象。本章所講的實(shí)例管理,就是對(duì)服務(wù)實(shí)例生命周期的管理,即讓服務(wù)實(shí)例按照我們希望的方式創(chuàng)建、存活和消亡,所以我們唯一的方式也只能是:在希望服務(wù)實(shí)例存活的時(shí)候讓它被某個(gè)“根”引用,從而阻止GC將其回收;在希望服務(wù)實(shí)例被回收的時(shí)候連“根”去除,使GC能夠?qū)⑵浠厥?。而本?jié)所講的實(shí)例上下文(InstanceContext)就扮演著“根”的角色。
說到實(shí)例上下文,相信讀者不會(huì)感到陌生,因?yàn)樵谶M(jìn)行WCF雙向(Duplex)通信的時(shí)候,我們通過實(shí)例上下文來封裝回調(diào)對(duì)象。在WCF中,實(shí)例上下文不僅僅用于對(duì)回調(diào)對(duì)象的封裝,也用于對(duì)真正服務(wù)實(shí)例的封裝。實(shí)際上可以將WCF的雙向通信理解成一種對(duì)等通信,通信的雙方是對(duì)等的參與者,并沒有嚴(yán)格的服務(wù)端和客戶端之分,或者說通信的雙方交替地扮演著服務(wù)與客戶的角色??蛻舳苏U{(diào)用服務(wù)端操作是一種服務(wù)調(diào)用;服務(wù)端回調(diào)客戶端操作也可以看成是一種服務(wù)調(diào)用。因此,通過實(shí)例上下文對(duì)回調(diào)對(duì)象和服務(wù)實(shí)例進(jìn)行封裝本質(zhì)上是一致的。
實(shí)例上下文對(duì)服務(wù)實(shí)例的封裝大體可以通過圖1表示。一個(gè)WCF服務(wù)通過一個(gè)ServiceHost進(jìn)行寄宿,并添加一到多個(gè)終結(jié)點(diǎn)。對(duì)于接收到的服務(wù)調(diào)用請(qǐng)求,如果相應(yīng)的實(shí)例上下文存在,則通過它得到服務(wù)實(shí)例來處理服務(wù)請(qǐng)求,否則創(chuàng)建服務(wù)實(shí)例并通過實(shí)例上下文對(duì)其進(jìn)行封裝,然后再通過實(shí)例上下文得到具體的服務(wù)實(shí)例進(jìn)行服務(wù)請(qǐng)求處理。

圖1 實(shí)例上下文對(duì)服務(wù)實(shí)例的封裝
實(shí)例上下文通過類型System.ServiceModel.InstanceContext表示。InstanceContext繼承自CommunicationObject,實(shí)現(xiàn)了IExtensibleObject
1: public sealed class InstanceContext : CommunicationObject, IExtensibleObject
2: {
3: //其他成員
4: public InstanceContext(object implementation);
5: public InstanceContext(ServiceHostBase host);
6: public InstanceContext(ServiceHostBase host, object implementation);
7:
8: public object GetServiceInstance();
9: public object GetServiceInstance(Message message);
10: public void ReleaseServiceInstance();
11:
12: public IExtensionCollectionExtensions { get; }
13: public ServiceHostBase Host { get; }
14: public ICollectionIncomingChannels { get; }
15: public ICollectionOutgoingChannels { get; }
16: public SynchronizationContext SynchronizationContext { get; set; }
17: }
InstanceContext具有三個(gè)構(gòu)造函數(shù),接受ServiceHostBase對(duì)象和具體的實(shí)例對(duì)象作為其輸入?yún)?shù)。GetServiceInstance和ReleaseServiceInstance用戶服務(wù)實(shí)例的獲取和釋放。IncomingChannels和OutgoingChannels則表示入棧和出棧信道集合。而通過SynchronizationContext屬性則可以設(shè)置或獲取用于異步操作的同步上下文,比如服務(wù)操作須要在非UI線程下操作一個(gè)Windows Form的控件,你就需要基于UI線程的同步上下文(SynchronizationContext)。
二、實(shí)例上下文模式(InstanceContext Mode)
實(shí)例上下文模式(IntanceContext Mode)表示服務(wù)端的服務(wù)實(shí)例與客戶端的服務(wù)代理的綁定方式。如果讀者熟悉.NET Remoting,肯定會(huì)很清楚.NET Remoting具有兩種不同的遠(yuǎn)程對(duì)象激活方式:服務(wù)端激活對(duì)象(SAO:Server Activated Object)和客戶端激活對(duì)象(CAO:Client Activated Object),而前者又具有兩種不同的變體:?jiǎn)握{(diào)(SingleCall)和單例(Singleton)。單調(diào)模式意味著服務(wù)端對(duì)于接收到的調(diào)用,都會(huì)創(chuàng)建新的遠(yuǎn)程對(duì)象,而單例模式則表示服務(wù)端使用相同的遠(yuǎn)程對(duì)象處理來自不同客戶端的所有遠(yuǎn)程調(diào)用。單調(diào)和單例模式體現(xiàn)了兩種極端的遠(yuǎn)程對(duì)象激活方式,而CAO則是一種相對(duì)折中的方式:一個(gè)客戶端代理對(duì)象與一個(gè)遠(yuǎn)程對(duì)象一一匹配。WCF實(shí)例上下文模式與.NET Remoting的遠(yuǎn)程對(duì)象激活方式類似,同樣具有三種不同的實(shí)例上下文模式,分別與上述三種激活方式匹配。這三種實(shí)例上下文模式分別是:?jiǎn)握{(diào)(Per-Call)模式、會(huì)話(Per-Session)模式和單例(Single)模式。
1、單調(diào)(Per-Call)模式
單調(diào)模式相當(dāng)于.NET Remoting的SingleCall遠(yuǎn)程對(duì)象激活方式。如果采用單調(diào)實(shí)例上下文模式,對(duì)于每一個(gè)服務(wù)調(diào)用,不論是來自相同的客戶端(服務(wù)代理)還是不同的客戶端,WCF總是創(chuàng)建一個(gè)全新的服務(wù)實(shí)例和實(shí)例上下文對(duì)象來處理服務(wù)調(diào)用請(qǐng)求。在服務(wù)操作執(zhí)行完畢,實(shí)例上下文對(duì)象和被封裝的服務(wù)實(shí)例被回收調(diào)。圖2揭示了在單調(diào)模式下實(shí)例上下文、服務(wù)實(shí)例和服務(wù)代理之間的關(guān)聯(lián)。

圖2 單調(diào)模式下服務(wù)代理與服務(wù)實(shí)例上下文之間的關(guān)聯(lián)
2、會(huì)話(Per-Session)模式
會(huì)話(Session)的目的在于保持來自相同客戶端(即同一個(gè)服務(wù)代理)多次服務(wù)調(diào)用之間的狀態(tài)。如果從消息交互的角度來講,通過會(huì)話可以將來自相同客戶端的多個(gè)消息關(guān)聯(lián)在一起。在會(huì)話實(shí)例上下文模式下,WCF為每一個(gè)服務(wù)代理對(duì)象分配一個(gè)單獨(dú)的服務(wù)實(shí)例上下文對(duì)象,對(duì)于來自相同服務(wù)代理的所有服務(wù)調(diào)用請(qǐng)求,都將分發(fā)給相同的服務(wù)實(shí)例上下文處理。會(huì)話模式與.NET Remoting下的CAO遠(yuǎn)程對(duì)象激活模式類似,圖3揭示了會(huì)話模式下實(shí)例上下文、服務(wù)實(shí)例和服務(wù)代理之間的關(guān)系。

圖3 會(huì)話模式下服務(wù)代理與服務(wù)實(shí)例上下文之間的關(guān)聯(lián)
3、單例(Single)模式
單例模式意味著WCF為每個(gè)服務(wù)維護(hù)一個(gè)并且僅維護(hù)一個(gè)服務(wù)實(shí)例上下文。不論請(qǐng)求來自相同的服務(wù)代理還是不同的服務(wù)代理,處理服務(wù)調(diào)用請(qǐng)求都是同一個(gè)服務(wù)實(shí)例上下文對(duì)象。單例模式相當(dāng)于.NET Remoting下的Singleton遠(yuǎn)程對(duì)象激活方式,圖4揭示了單例模式下實(shí)例上下文、服務(wù)實(shí)例和服務(wù)代理之間的關(guān)系。

圖4 會(huì)話模式下服務(wù)代理與服務(wù)實(shí)例上下文之間的關(guān)聯(lián)
三、 實(shí)例服務(wù)行為
在介紹服務(wù)寄宿的時(shí)候,我們談到過WCF下“契約(Contract)”和“行為(Behavior)”的區(qū)別:契約是涉及雙邊的描述(契約是服務(wù)的提供者和服務(wù)消費(fèi)者進(jìn)行交互的手段),那么行為就是基于單邊的描述??蛻舳诵袨轶w現(xiàn)的是WCF如何進(jìn)行服務(wù)調(diào)用的方式,而服務(wù)端行為則體現(xiàn)了WCF的請(qǐng)求分發(fā)方式。所以服務(wù)契約會(huì)通過元數(shù)據(jù)對(duì)外發(fā)布,而服務(wù)行為則對(duì)于客戶端是透明的。
對(duì)于客戶端來講,它所關(guān)心的是通過服務(wù)調(diào)用能夠獲得正確的結(jié)果,而不會(huì)關(guān)心服務(wù)端采用怎樣的模式來激活服務(wù)實(shí)例。所以,WCF實(shí)例管理通過服務(wù)行為體現(xiàn),不同的實(shí)例上下文模式通過ServiceBehaviorAttribute特性指定。在ServiceBehaviorAttribute中,通過設(shè)置InstanceContextMode屬性來指定不同的服務(wù)實(shí)例上下文模式。
1: [AttributeUsage(AttributeTargets.Class)]
2: public sealed class ServiceBehaviorAttribute : Attribute, IServiceBehavior
3: {
4: //其他成員
5: public InstanceContextMode InstanceContextMode { get; set; }
6: }
屬性InstanceContextMode的類型為System.ServiceModel.InstanceContextMode枚舉,三個(gè)枚舉值PerCall、PerSession和Single分別表示上述的三種實(shí)例上下文模式。默認(rèn)選項(xiàng)為PerSession。
1: public enum InstanceContextMode
2: {
3: PerCall,
4: PerSession,
5: Single
6: }
在本系列后續(xù)部分,我將對(duì)每一種實(shí)例模式的實(shí)現(xiàn)原理進(jìn)行逐個(gè)剖析,相信極大的加深讀者對(duì)WCF下的服務(wù)對(duì)象生命周期管理機(jī)制的理解。
編輯:hfy
-
寄存器
+關(guān)注
關(guān)注
31文章
5590瀏覽量
129248 -
WCF
+關(guān)注
關(guān)注
0文章
4瀏覽量
7098
發(fā)布評(píng)論請(qǐng)先 登錄
探索 XENSIV? Game Controller:創(chuàng)新游戲控制器的技術(shù)剖析
探索DS160PR822:高性能PCIe 4.0線性轉(zhuǎn)接驅(qū)動(dòng)器的技術(shù)剖析與應(yīng)用指南
AMD UltraScale架構(gòu):高性能FPGA與SoC的技術(shù)剖析
DLPC3420顯示控制器:技術(shù)剖析與應(yīng)用指南
ProfiNet嵌入式板卡,主流替代可實(shí)現(xiàn)ProfiNet工業(yè)以太網(wǎng)的應(yīng)用實(shí)例
Modbus協(xié)議的深度剖析
RS485轉(zhuǎn)PROFIBUS DP網(wǎng)關(guān)寫入命令讓JRT激光測(cè)距傳感器開啟慢速模式連續(xù)測(cè)量
【「DeepSeek 核心技術(shù)揭秘」閱讀體驗(yàn)】--全書概覽
實(shí)例解讀模擬電子技術(shù)
UIAbility組件啟動(dòng)模式:實(shí)例在啟動(dòng)時(shí)的不同呈現(xiàn)狀態(tài)
電機(jī)故障診斷常見誤區(qū)的剖析
直流電源CV/CC模式實(shí)現(xiàn)原理
深入剖析智芯傳感開口封封裝技術(shù)
全面剖析倒裝芯片封裝技術(shù)的內(nèi)在機(jī)制、特性優(yōu)勢(shì)、面臨的挑戰(zhàn)及未來走向
BNC接頭技術(shù)原理與工程應(yīng)用剖析:從結(jié)構(gòu)到性能優(yōu)化

WCF技術(shù)的實(shí)例模式的實(shí)現(xiàn)原理剖析
評(píng)論