セッション、インスタンス化、および同時実行
"セッション" とは、2 つのエンドポイント間で送信されるすべてのメッセージを相互に関連付けたものです。"インスタンス化" とは、ユーザー定義のサービス オブジェクトとこれらのオブジェクトに関連する InstanceContext オブジェクトの有効期間を制御することです。また、同時実行は、InstanceContext で同時に実行されるスレッドの数の制御を表す用語です。
ここでは、これらの設定とその使用方法、各設定間のさまざまな相互作用について説明します。
セッション
サービス コントラクトによって System.ServiceModel.ServiceContractAttribute.SessionMode プロパティが System.ServiceModel.SessionMode.Required に設定されている場合、すべての呼び出し (つまり、呼び出しをサポートする、基になるメッセージ交換) を同じメッセージ交換の一部にする必要があります。セッションが許可されるが必須ではないコントラクトの場合、クライアントは、接続した後にセッションを確立できます。また、セッションを確立しないままにしておくこともできます。セッションが終了したのに、同じセッション ベースのチャネルでメッセージが送信されると、例外がスローされます。
WCF セッションには、次のような主要な概念的特徴があります。
呼び出し側アプリケーションによって明示的に開始および終了される。
セッション中に配信されたメッセージは、受信された順に処理される。
セッションはメッセージのグループを相互に関連付けて通信を行う。ここで "相互に関連付ける" は、抽象的な意味を持ちます。たとえば、あるセッション ベースのチャネルでは、共有ネットワーク接続に基づいてメッセージが相互に関連付けられる一方、別のセッション ベースのチャネルでは、メッセージ本文にある共有タグに基づいてメッセージが相互に関連付けられます。セッションから派生可能な機能は、相互関連付けの性質によって異なります。
WCF セッションに関連付けられた一般的なデータ ストアはありません。
ASP.NET アプリケーションの System.Web.SessionState.HttpSessionState クラスに精通している場合は、この種のセッションと WCF セッションの間に次のような相違があることがわかります。
ASP.NET セッションは、常にサーバーによって開始される。
ASP.NET セッションは、暗黙的に順序付けされない。
ASP.NET セッションは、要求全体について一般的なデータ ストレージ機構を提供する。
クライアント アプリケーションとサービス アプリケーションでは、異なる方法でセッションと対話します。クライアント アプリケーションはセッションを開始し、セッション内で送信されてきたメッセージの受信と処理を行います。サービス アプリケーションでは、動作を追加するための機能拡張ポイントとしてセッションを使用できます。これは InstanceContext を直接操作する、またはカスタムのインスタンス コンテキスト プロバイダーを実装することで可能になります。
インスタンス化
インスタンス化動作 (System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode プロパティを使用して設定します) は、受信メッセージに応答して InstanceContext を作成する方法を制御します。既定では、各 InstanceContext は 1 つのユーザー定義サービス オブジェクトに関連付けられています。したがって、(既定では) InstanceContextMode プロパティを設定することによってもユーザー定義サービス オブジェクトのインスタンス化を制御できます。インスタンス化モードは InstanceContextMode 列挙体によって定義されます。
次のインスタンス化モードを使用できます。
PerCall : 新しい InstanceContext (およびサービス オブジェクト) がクライアント要求ごとに作成されます。
PerSession : 新しい InstanceContext (およびサービス オブジェクト) が新しいクライアント セッションごとに作成され、そのセッションの有効期間中、保持されます (ただし、セッションをサポートするバインディングが必要です)。
Single : アプリケーションの有効期間中は、単一の InstanceContext (およびサービス オブジェクト) がすべてのクライアント要求を処理します。
既定の InstanceContextMode 値 (サービス クラスで明示的に設定された PerSession) を次のコード例に示します。
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class CalculatorService : ICalculatorInstance
{
...
}
また、System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode プロパティは InstanceContext の解放頻度を制御しますが、System.ServiceModel.OperationBehaviorAttribute.ReleaseInstanceMode プロパティと System.ServiceModel.ServiceBehaviorAttribute.ReleaseServiceInstanceOnTransactionComplete プロパティはサービス オブジェクトの解放時期を制御します。
既知のシングルトン サービス
単一インスタンス サービス オブジェクトの 1 つのバリエーションとして、サービス オブジェクトをユーザーが自分で作成し、このオブジェクトを使用してサービス ホストを作成すると有用な場合があります。そのためには、System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode プロパティを Single に設定するか、サービス ホストが開かれたときに例外をスローする必要があります。
このようなサービスを作成するには、System.ServiceModel.ServiceHost.#ctor(System.Object,System.Uri[]) コンストラクターを使用します。この方法は、シングルトン サービスが使用する特定のオブジェクト インスタンスを提供する場合に、カスタムの System.ServiceModel.Dispatcher.IInstanceContextInitializer を実装する代わりに使用できます。サービス実装の型を作成することが困難な場合 (たとえば、既定のパラメーターなしのコンストラクターが作成されない場合) は、このオーバーロードを使用できます。
オブジェクトをこのコンストラクターに提供すると、Windows Communication Foundation (WCF) のインスタンス化動作に関するいくつかの機能が異なる動作をすることに注意してください。たとえば、シングルトン オブジェクト インスタンスを指定しているときは、System.ServiceModel.InstanceContext.ReleaseServiceInstance を呼び出しても効果はありません。他のインスタンス解放機構も、同様に無視されます。ServiceHost は常に、すべての操作について System.ServiceModel.OperationBehaviorAttribute.ReleaseInstanceMode プロパティが System.ServiceModel.ReleaseInstanceMode.None に設定されているかのように動作します。
InstanceContext オブジェクトの共有
ユーザーが自ら関連付けを行うことにより、どの InstanceContext オブジェクトに、どのセッションフル チャネルまたは呼び出しを関連付けるかを制御することもできます。詳細な例については、「InstanceContextSharing」を参照してください。
同時実行
同時実行は、InstanceContext 内で同時にアクティブになるスレッドの数を制御します。同時実行を制御するには、System.ServiceModel.ServiceBehaviorAttribute.ConcurrencyMode と ConcurrencyMode 列挙値を使用します。
選択可能な同時実行モードは次の 3 つです。
Single: 各インスタンス コンテキストは、そのインスタンス コンテキスト内でメッセージを処理するスレッドを最大で一度に 1 つ持つことができます。他のスレッドは、最初のスレッドがインスタンス コンテキストを使用し終えるまで、同じインスタンス コンテキストを使用できません。
Multiple: 各サービス インスタンスは、同時にメッセージを処理する複数のスレッドを持つことができます。この同時実行モードを使用するには、サービスの実装がスレッドセーフである必要があります。
Reentrant : 各サービス インスタンスは、一度に 1 つのメッセージを処理しますが、再入操作の呼び出しを受け入れます。サービスは、WCF クライアント オブジェクトを通じて呼び出しを行う場合のみ、この呼び出しを受け入れます。
注 : |
---|
複数のスレッドを安全に使用するコードを理解し、適切に記述することが困難な場合もあります。Multiple 値や Reentrant 値を使用する前に、これらのモード用にサービスが適切に設計されていることを確認してください。詳細については、次のトピックを参照してください。 ConcurrencyMode. |
同時実行の使用は、インスタンス化モードに関連します。PerCall インスタンス化では、各メッセージが新しい InstanceContext によって処理され、InstanceContext で複数のスレッドがアクティブになることはないため、同時実行とは関連しません。
ConcurrencyMode プロパティを Multiple に設定するコード例を次に示します。
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
public class CalculatorService : ICalculatorConcurrency
{
...
}
InstanceContext 設定と対話するセッション
セッションと InstanceContext は、コントラクト内の SessionMode 列挙値と、チャネルと特定のサービス オブジェクト間の関連付けを制御するサービス実装の System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode プロパティ値の組み合わせに応じて、相互に作用します。
サービスの System.ServiceModel.ServiceContractAttribute.SessionMode プロパティと System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode プロパティの値の組み合わせが指定されているという条件で、セッションをサポートしている受信チャネルまたはサポートしていない受信チャネルの結果を次の表に示します。
InstanceContextMode 値 | Required | Allowed | NotAllowed |
---|---|---|---|
PerCall |
|
|
|
PerSession |
|
|
|
Single |
|
|
|
参照
処理手順
方法 : セッションを必要とするサービスを作成する
方法 : サービスのインスタンス化を制御する
同時実行
インスタンス化
セッション