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