標籤:
當發生一次WCF要求-回應操作時,會經過如下幾個步驟
- WCF Client想WCF Server發送一個服務要求
- WCF Server建立WCF服務物件
- WCF Server調用WCF服務物件介面,將結果返回給WCF用戶端。
操作過程中就牽涉到了服務物件的建立,但由於WCF服務物件是WCF架構管理,一般的時候並不關注它何時建立,何時回收。對於無需訪問成員變數的狀態無關的服務來說,這個並不影響我們的功能實現。
但是,許多時候我們也需要提供與狀態相關的服務,這個時候需要通過服務物件的成員變數來儲存狀態。此時,我們就需要關注WCF的服務物件的建立策略了。下面就以一個計數器為例,介紹一下不同的策略對服務結果的影響。
[ServiceContract]
public interface IService1
{
[OperationContract]
int Increment();
}
[ServiceBehavior]
public class Service1 : IService1
{
private int intCounter;
public int Increment()
{
intCounter++;
return intCounter;
}
}
一般來講,我們有如下三種策略建立WCF對象:
- PerCall 每次WCF服務調用都建立一個新的WCF服務物件,
- PerSession 每個WCF會話期間只建立一個WCF服務物件,如果沒有會話設定,則效果同PerCall(預設策略)
- Single 所有WCF會話共用一個WCF服務物件
這三種策略可以ServiceBehavior在中通過InstanceContextMode顯式設定。
ServiceBehavior(public class Service1 : IService1
注意:由於如果會話沒有啟用的話的話,PerSession效果同PerCall,而預設的協議basicHttpBinding不支援會話,為了正確示範這個樣本,請將協議綁定到wsHttpBinding。
PerCall模式:
在這種方式下,每次WCF服務調用都建立一個新的WCF服務物件,調用完請求後,該對象便進入可回收狀態。
在這種方式下,無論用戶端如何調用,由於每次都是建立新對象,則計數永遠都是1
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service1 : IService1
{
}
PerSession模式
在這種模式下,每個會話對應一個服務物件,會話結束後服務物件被回收。也就是說:
- 同一個用戶端的所有調用都發送給同一個服務物件
- 不同的用戶端的調用發送給不同的服務物件
在這種方式下,每一個用戶端都是獨立計數的。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class Service1 : IService1
{
}
Single模式
在這種模式下,所有會話都對應同一個服務物件。
這個方式下,所有的用戶端的計數都會被累加起來。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class Service1 : IService1
{
}
服務物件生命週期和Dispose
雖然我們通過InstanceContextMode控制服務物件的生命週期,但是我們也無法得之服務物件何時釋放。一般情況下,這個確實無需關心,但是,如果服務物件中如果在成員變數中儲存了資源,我們就得需要確保資源能夠及時釋放。
按照.net設計原則,如果成員中儲存了資源,則需要實現IDisposable介面,然後再Dispose方法中釋放資源。實際上,在WCF中也是遵循這個規則的:對於實現了IDisposable介面的服務物件,在該對象生命週期結束後,就會調用其Dispose方法以確保及時釋放資源。也就是說,只要我們的實現符合基礎的設計準則,WCF架構自動及時釋放。
活用一下這個規則:我們可以利用Dispose方法感知會話模式下成員的下線。
三種方式的比較
從效能上來看,Single模式全域只建立一個對象,開銷最小。而PerCall每次調用都建立一個對象,看起來開銷最大,但是它的可擴充性是最好的,非常容易實現負載分擔,並且資源釋放最為及時。
從功能上來看,PerSession和物件導向的模式最為接近,實現各種複雜的邏輯更為容易。
WCF入門(十)——服務物件模型