3

私は nettcpbinding サービスを持っていて、それを Windows サービスでホストしています。サービスはネットワーク上で動作する必要があり、100 を超えるクライアントからの受信メッセージを処理します。

問題: すべてのセッションがアクセスできるプロパティが必要です。このような :

class a
{
   list<string> strList=new list<string>();

class b{}
class c{}
...
}

この例では、すべてのクラスが strList にアクセスできます。すべてのセッションがアクセスできるリストが必要です(そのリストに追加または削除します)。

サービス構成はバッファリングされ、セキュリティはありません。サービス属性は次のとおりです。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
[ServiceContract(SessionMode = SessionMode.Required)]

編集: 1 つの例にすぎないクラスを作成したくありません。すべてのセッションがそれにアクセスできるリストが必要です.InstanceContextMode.PerSessionサービスがあり、サービスクラスが各クライアントごとに作成すると、各クライアントには独自のサービスクラスがあり、作成された各セッションが1つのパブリックリストにアクセスできるようになります.

EDIT2: このリストはサーバーにあり、サーバーだけがアクセスでき、リストをクライアントに送信する必要はありません。何かを計算するためのサーバー変数です。

4

3 に答える 3

6

たとえば、サービス クラスで静的プロパティを使用できます。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
[ServiceContract(SessionMode = SessionMode.Required)]
public class MyService : IMyService {

    // this is your static data store which is accessible from all your sessions
    private static List<string> strList = new List<string>();

    // an object to synchronize access to strList
    private static object syncLock = new object();

    public void AddAction(string data) {

        // be sure to synchronize access to the static member:
        lock(syncLock) {
            strList.Add(data);
        }
    }

}

WCF は、サービスに接続する新しいクライアントごとに MyService の新しいインスタンスを作成します。それらはすべて静的プロパティにアクセスできます。

于 2012-10-31T14:03:41.513 に答える
2

おそらく ConcurrencyMode を Multiple に設定する必要があり、オブジェクトをマルチスレッドとして扱うようにする必要があります。複数のロックを必要とするこの状況でデッドロックを回避するパターンがあります。詳細については、この MSDN の記事を参照してください

[SerivceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
class MyService : IMyContract
{

//Here is your shared object
static List<string> _strList = new List<string>();

//Only access the property for thread safety, not the variable
static List<string> StrList
{
    get
    {
        lock(typeof(MyService)
        {
            return _strList;
        }
    }
    set
    {
        lock(typeof(MyService)
        {
            _strList = value;
        }
    }
}

void DoSomeThing()
{
    lock(typeof(MyService))
    {
        //Do something with your list here, other threads are blocked from accessing
        // objects in lock
        StrList.Add("Something");
    }
}
}

ただし、コレクションの使用を検討している場合は、マルチスレッド アクセス用に作成されたConcurrency Collectionオブジェクトを確認することをお勧めします。これらのオブジェクトは、自己完結型のロックを備えているため、ロックの必要がなくなります。これは、将来忘れた場合に便利です。

EDIT:情報を追加するだけで、ロックは他のスレッドがそのロックでコードを実行したり、ロックされたプロパティにアクセスしたりするのをブロックします。このため、すべてのクライアントの速度が低下する可能性があるため、ロックでの長時間の操作はお勧めしません。さらに、InstanceContextMode を PerCall に設定すると、サービスへの呼び出しごとにサービス クラスの新しいインスタンスが作成されます。逆に、アクティビティがなく、すべてのサービス インスタンスがクリーンアップまたはクローズされた場合、共有オブジェクトも失われます。

于 2012-10-31T13:57:59.997 に答える
0

DataContract を構築する必要があると思います

例 :

  [DataContract]
    public class A
    {
     [DataMember]
     list<string> strList { get; set; }

     class B
       {
       }

     class C
       {
       }
   }
于 2012-10-31T08:08:08.383 に答える