工作階段、執行個體與並行

工作階段 」(Session) 是兩個端點之間所傳送之所有訊息的相互關聯。 「執行個體 」(Instancing) 是指控制使用者定義之服務物件的存留時間,以及其相關的 InstanceContext 物件。 「並行 」(Concurrency) 是指控制在 InstanceContext 中同時執行的執行緒數目。

本主題將說明這些設定、這些設定的使用方式,以及這些設定間的各種互動。

研討會

當服務合約將 ServiceContractAttribute.SessionMode 屬性設定為 SessionMode.Required時,該合約會指出所有的呼叫 (即支援呼叫的基礎訊息交換模式) 必須是同一個對話的一部分。 如果合約指定其允許工作階段,但不需要工作階段,則用戶端可以連線,並選擇是否要建立工作階段。 如果工作階段終止並透過相同之工作階段型的通道傳送訊息,就會擲回例外狀況。

WCF 會話具有下列主要概念功能:

  • 工作階段是由呼叫的應用程式明確地初始化及終止。

  • 工作階段期間傳遞的訊息是依其接收的順序進行處理。

  • 工作階段會將一群訊息互相關聯為對話。 此相互關聯的意義是一種抽象概念。 例如,某個工作階段架構通道可能會根據共用的網路連線將訊息相互關聯,而另一個工作階段架構通道可能會根據訊息本文內的共用標記將訊息相互關聯。 這些可以衍生自工作階段的功能視相互關聯的本質而定。

  • 沒有與 WCF 會話相關聯的一般資料存放區。

如果您熟悉 System.Web.SessionState.HttpSessionState ASP.NET 應用程式中的類別,以及它所提供的功能,您可能會注意到這種會話和 WCF 會話之間有下列差異:

  • ASP.NET 的會話一律是由伺服器起始。

  • ASP.NET 的會話會隱含地未排序。

  • ASP.NET 會話可提供跨要求的一般資料儲存機制。

用戶端應用程式和服務應用程式會以不同的方式與工作階段互動。 用戶端應用程式會初始化工作階段,接著並接收及處理在工作階段內傳送的訊息。 服務應用程式可以將工作階段當做擴充點使用,以便加入其他行為。 其做法是直接使用 InstanceContext 或實作自訂的執行個體內容提供者。

實例

執行個體行為 (使用 ServiceBehaviorAttribute.InstanceContextMode 屬性設定) 會控制 InstanceContext 對傳入訊息建立回應的方法。 根據預設,每一個 InstanceContext 都會與一個使用者定義的服務物件產生關聯,因此 (在預設的情形下) 設定 InstanceContextMode 屬性也會控制使用者定義之服務物件執行個體。 InstanceContextMode 列舉型別 (Enumeration) 會定義執行個體模式。

以下為可用的執行個體模式:

  • PerCall:為每個用戶端要求所建立的新 InstanceContext (因此為服務物件)。

  • PerSession:為每個新用戶端工作階段所建立的新 InstanceContext (因此為服務物件),並維持該工作階段的存留期 (這麼做需要支援工作階段的繫結)。

  • Single:單一的 InstanceContext (因此為服務物件),負責處理所有應用程式之存留期的用戶端要求。

下列程式碼範例示範預設的 InstanceContextMode 值,在服務類別上會明確地設定 PerSession

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class CalculatorService : ICalculatorInstance
{
    ...  
}  

ServiceBehaviorAttribute.InstanceContextMode 屬性控制釋放 InstanceContext 的頻率時, OperationBehaviorAttribute.ReleaseInstanceModeServiceBehaviorAttribute.ReleaseServiceInstanceOnTransactionComplete 屬性會控制釋放服務物件的時機。

已知的單一服務

單一執行個體服務物件的其中一個變化有時可能會很有用處:您可以自行建立服務物件,並建立使用該物件的服務主機。 若要這麼做,您必須同時將 ServiceBehaviorAttribute.InstanceContextMode 屬性設定為 Single ,否則在開啟服務主機時會擲回例外狀況。

請使用 ServiceHost(Object, Uri[]) 建構函式建立此類服務。 當您想要將特定物件執行個體提供給單一服務使用時,它提供了另一種實作自訂 System.ServiceModel.Dispatcher.IInstanceContextInitializer 的方式。 當您的服務實類型很難建立時,您可以使用這個多載 (例如,如果它不會執行無參數的公用函式) 。

請注意,當物件提供給此函式時,與 Windows Communication Foundation (WCF) 實例行為相關的某些功能會以不同的方式運作。 例如,提供單一物件執行個體時,呼叫 InstanceContext.ReleaseServiceInstance 將沒有任何作用。 同樣的,也會忽略任何其他執行個體的釋放機制。 ServiceHost 的行為就像是所有作業都已將 OperationBehaviorAttribute.ReleaseInstanceMode 屬性設定為 ReleaseInstanceMode.None

共用 InstanceContext 物件

您也可以自行執行該關聯,以控制哪個工作階段通道或呼叫應與哪個 InstanceContext 物件產生關聯。

並行

並行是指控制在 InstanceContext 內同時為作用中的執行緒數目。 這是透過使用 ServiceBehaviorAttribute.ConcurrencyModeConcurrencyMode 列舉型別的方式予以控制。

以下為可用的三種並行模式:

  • Single:每一個執行個體內容同時最多可以在執行個體內容中,擁有一個處理訊息的執行緒。 其他希望使用相同執行個體內容的執行緒必須封鎖,直到原始的執行緒結束執行個體內容為止。

  • Multiple:每一個服務執行個體都可以同時擁有多個處理訊息的執行緒。 此服務實作必須是安全執行緒,才能使用這種並行模式。

  • Reentrant:每一個服務執行個體在同一時間內會處理一個訊息,但接受可重新進入 (Re-entrant) 的作業呼叫。 服務只會在透過 WCF 用戶端物件呼叫時,接受這些呼叫。

注意

您應該了解,開發能夠安全地使用一個以上之執行緒的程式碼,可能會很難順利地撰寫。 在使用 MultipleReentrant 值之前,請確定已適當地設計您的服務以使用這些模式 如需詳細資訊,請參閱ConcurrencyMode

並存的使用與執行個體模式有關。 在 PerCall 實例中,並行與不相關,因為每個訊息都是由新的所處理,因此在中永遠不會有 InstanceContext 一個以上的執行緒在作用中 InstanceContext

下列程式碼會示範將 ConcurrencyMode 屬性設定為 Multiple

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public class CalculatorService : ICalculatorConcurrency
{
    ...  
}  

與 InstanceContext 設定互動的工作階段

工作階段和 InstanceContext 會根據合約內 SessionMode 列舉型別值的組合以及服務實作上的 ServiceBehaviorAttribute.InstanceContextMode 屬性而進行互動,以控制通道與特定服務物件的關聯。

下表根據服務的 ServiceContractAttribute.SessionMode 屬性與 ServiceBehaviorAttribute.InstanceContextMode 屬性等值的組合,說明支援工作階段或不支援工作階段之傳入通道的結果。

InstanceContextMode 值 Required Allowed NotAllowed
PerCall -會話通道的行為:會話與 InstanceContext 每個呼叫的。
-無會話通道的行為:擲回例外狀況。
-會話通道的行為:會話與 InstanceContext 每個呼叫的。
-無會話通道的行為: InstanceContext 每個呼叫的。
-會話通道的行為:擲回例外狀況。
-無會話通道的行為: InstanceContext 每個呼叫的。
PerSession -會話通道的行為:會話與 InstanceContext 每個通道的。
-無會話通道的行為:擲回例外狀況。
-會話通道的行為:會話與 InstanceContext 每個通道的。
-無會話通道的行為: InstanceContext 每個呼叫的。
-會話通道的行為:擲回例外狀況。
-無會話通道的行為: InstanceContext 每個呼叫的。
Single -會話通道的行為:會話,以及一個 InstanceContext 用於所有呼叫。
-無會話通道的行為:擲回例外狀況。
-會話通道的行為:會話和 InstanceContext 針對已建立或使用者指定的 singleton。
-無會話通道的行為: InstanceContext 適用于所建立或使用者指定之 singleton 的。
-會話通道的行為:擲回例外狀況。
-無會話通道的行為: InstanceContext 每個建立的 singleton 或使用者指定的 singleton 的。

另請參閱