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)]

编辑: 我不想创建只是一个例子的类。我只需要一个所有会话都可以访问它的列表。当您拥有 InstanceContextMode.PerSession 服务时,该服务类将为每个客户端创建,然后每个客户端都有自己的服务类,现在我希望创建的每个会话都可以访问一个公共列表。

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");
    }
}
}

但是,如果您正在考虑使用集合,我建议您查看并发集合对象,因为这些对象是为多线程访问而设计的。这些对象不需要锁定,因为它们具有自包含锁定,这在您将来忘记的情况下很好。

编辑:只是为了补充信息,锁定将阻止其他线程执行该锁中的代码或访问锁定的属性。出于这个原因,不建议在锁中进行冗长的操作,因为它会减慢所有客户端的速度。此外,您的 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 回答