Jimmy McNulty が言ったように、1 つのオプションは静的メンバーを使用することです。ユーザー指定の IP アドレスに基づいてネットワーク接続を開く WCF サービスがあります。私のサービスは、PerCall サービス インスタンス モード用に構成されています。各セッションで、静的データ構造をチェックして、指定された IP アドレスに対してネットワーク接続が既に開かれているかどうかを確認します。これが例です。
[ServiceContract]
public interface IMyService
{
[OperationContract]
void Start(IPAddress address);
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class MyService : IMyService
{
private static readonly List<IPAddress> _addresses = new List<IPAddress>();
public void Start(IPAddress address)
{
lock(((ICollection)_addresses).SyncRoot)
{
if (!_addresses.Contains(address)
{
// Open the connection here and then store the address.
_addresses.Add(address);
}
}
}
}
構成されているように、Start() への各呼び出しは独自のサービス インスタンス内で発生し、各インスタンスは静的コレクションにアクセスできます。各サービス インスタンスは個別のスレッド内で動作するため、コレクションへのアクセスを同期する必要があります。
マルチスレッド プログラミングで行われるすべての同期と同様に、ロックに費やされる時間を最小限に抑えるようにしてください。示されている例では、最初の呼び出し元がロックを取得すると、他のすべての呼び出し元はロックが解放されるまで待機する必要があります。これは私の状況では機能しますが、あなたの状況では機能しない場合があります。
もう 1 つのオプションは、PerCall サービス インスタンス モードではなく、Single サービス インスタンス モードを使用することです。
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class MyService : IMyService
{ ... }
しかし、私が読んだすべてのことから、PerCall はより柔軟に見えます。
2 つの違いについては、このリンクをたどることができます。
また、サービスを実装するクラスはまさにクラスであることを忘れないでください。すべての C# クラスと同じように機能します。静的コンストラクター、プロパティ、イベント ハンドラーを追加したり、追加のインターフェイスを実装したりできます。