如何创建WCF服务中的所有会话都可以访问的属性?

时间:2012-10-31 08:00:17

标签: c# wcf service windows-services nettcpbinding

我有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: 这个列表在服务器中,只是服务器可以访问它不需要发送列表到客户端。它是服务器变量,用于计算某些东西。

3 个答案:

答案 0 :(得分:5)

您可以在服务类中使用静态属性,例如:

[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实例。 他们都可以访问静态属性。

答案 1 :(得分:2)

您可能希望将ConcurrencyMode设置为Multiple,并且需要确保将对象视为多线程,因为这是您基本上设置的。在这种需要多次锁定的情况下,有一种模式可以避免死锁。请参阅This MSDN article for details

[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对象,因为它们是为多线程访问而设计的。这些对象需要锁定,因为它们具有自锁锁定,这在将来忘记的情况下很好。

编辑:只是为了添加信息,锁定将阻止其他线程执行该锁中的代码或访问锁定的属性。出于这个原因,不建议在锁定中使用冗长的操作,因为它会减慢所有客户端的速度。此外,您设置为PerCall的InstanceContextMode将为您的服务的每个CALL创建服务类的新实例。反之,如果您没有任何活动并且所有服务实例都被清理或关闭,那么您也将失去共享对象。

答案 2 :(得分:0)

我认为你应该构建一个DataContract

示例:

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

     class B
       {
       }

     class C
       {
       }
   }