Wcf-instance-management
WCF-インスタンス管理
WCFが一連のメッセージ(クライアント要求)をサービスインスタンスにバインドするために使用する一連の手法は、インスタンス管理と呼ばれます。 WCFは3種類のインスタンスのアクティブ化をサポートしています。これらについては、この章で説明します。
コールごとのサービス
呼び出しごとのサービスは、WCFの既定のインスタンスアクティブ化モードです。 WCFサービスがコールごとのサービス用に構成されている場合、CLRオブジェクトは、クライアントの呼び出しまたは要求が進行中のタイムスパンに対して作成されます。 CLRはCommon Language Runtimeの略で、WCFのサービスインスタンスが含まれています。
コールごとのサービスでは、すべてのクライアントリクエストが新しい専用サービスインスタンスを達成し、そのメモリ消費は他のタイプのインスタンスアクティベーションと比較して少なくなります。
WCFサービスが呼び出しごとのサービスとして機能することを示すには、InstanceContextModeプロパティをInstanceContextMode.PerCallに設定する必要があります。 InstanceContextModeプロパティはServiceBehavior属性に属します。 したがって、コールごとのサービスは次のように構成できます-
[ServiceContract]
interface IMyContract
{...}
[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerCall)]
class MyService : IMyContract
{...}
ここでは、サービスはIMyContractとして表されます。 次の図は、コールごとのサービスインスタンスのアクティブ化のプロセスを示しています。
コールごとのサービスの実装
[DataContract]
class Param {....}
[ServiceContract]
interface IMyContract {
[OperationContract]
void MyMethod(Param objectIdentifier);
}
class MyPerCallService : IMyContract, IDisposable {
public void MyMethod(Param objectIdentifier) {
GetState(objectIdentifier);
DoWork();
SaveState(objectIdentifier);
}
void GetState(Param objectIdentifier) {....}
void DoWork() {....}
void SaveState(Param objectIdentifier) {....}
public void Dispose() {....}
}
ここで、Paramは上記の例のために考案された擬似型パラメーターです。
セッションごとのサービス
このWCFのアクティブ化モードでは、プライベートセッションまたは2つのエンティティ、つまりクライアントと特定のサービスインスタンスの間で機密セッションが維持されます。 プライベートセッションサービスとも呼ばれるセッションごとのサービスは、各クライアントリクエスト専用であり、そのセッション対応サービスに関連する他のすべてのインスタンスから独立した新しいサービスインスタンスを提供します。
セッションごとのサービスを開始するには、InstanceContextModeプロパティをPerSessionに設定する必要があります。 この場合、サービスインスタンスはセッション期間中ずっとメモリに残ります。
アクティベーションモードは、この専用サービスインスタンスのそれぞれにかかるコストのために、構成済みのサービスが少数(または最大で数百)以外の追加の未処理のクライアントをサポートできないため、スケーラビリティが低下します。
セッションごとのサービスは次のように構成できます-
[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract
{...}
セッションごとのサービスのプロセスは、次の図に示すように説明することができます-
次のコードは、プライベートセッションの使用のために構成されたコントラクトとサービスを示しています。 出力は、クライアントが実際に専用のサービスインスタンスを取得したことを示しています。
サービスコード
[ServiceContract(Session = true)]
interface IMyContract {
[OperationContract]
void MyMethod();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract, IDisposable {
int m_Counter = 0; MyService() {Console.WriteLine("MyService.MyService()"); }
public void MyMethod() {
m_Counter++;
Console.WriteLine("Counter = " + m_Counter);
}
public void Dispose() {
Console.WriteLine("MyService.Dispose()");
}
}
クライアントコード
MyContractProxy proxy = new MyContractProxy(); proxy.MyMethod(); proxy.MyMethod();
proxy.Close();
出力
MyService.MyService() Counter = 1 Counter = 2 MyService.Dispose()
シングルトンサービス
このWCFのアクティブ化モードでは、相互に独立したすべてのクライアント要求は、サービスエンドポイントへの接続に関係なく、同じ既知の単一インスタンスに接続されます。 シングルトンサービスは、ホストが閉じられたときにのみ破棄されます。
このサービスは、ホストの作成時に一度だけ作成されます。 ホストにシングルトンインスタンスが提供されない場合、サービスはNULLを返します。 アクティブ化モードは、各メソッド呼び出しの作業量が少なく、バックグラウンドで保留中の操作がない場合に最適です。
このシングルトンサービスを開始するには、InstanceContextModeプロパティをInstanceContextMode.Singleに設定する必要があります。
したがって、シングルトンサービスは次のように構成できます-
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MySingleton : ...
{...}
シングルトンサービスのプロセスは、次の図に示されています-
次のコードは、シングルトンインスタンスの初期化とホストに使用されます。
サービスコード
[ServiceContract]
interface IMyContract {
[OperationContract]
void MyMethod( );
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MySingleton : IMyContract {
int m_Counter = 0;
public int Counter {
get {
return m_Counter;
}
set {
m_Counter = value;
}
}
public void MyMethod( ) {
m_Counter++;
Trace.WriteLine("Counter = " + Counter);
}
}
ホストコード
MySingleton singleton = new MySingleton( );
singleton.Counter = 42;
ServiceHost host = new ServiceHost(singleton);
host.Open( );
//Do some blocking calls then
host.Close( );
クライアントコード
MyContractClient proxy = new MyContractClient( );
proxy.MyMethod( );
proxy.Close( );
出力
Counter = 43