简体   繁体   English

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

[英]How do I create a property that all sessions in a WCF service have access to?

i have nettcpbinding service and host it with windows service. 我有nettcpbinding服务,并用Windows服务托管它。 the service must work on network and it handle incoming message comes from more than 100 clients. 该服务必须在网络上运行,并且它处理来自100多个客户端的传入消息。

Problem : I want have a property that all session can access to it . 问题:我想要一个所有会话都可以访问的属性。 like this : 像这样 :

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

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

in this example all class can access to strList. 在此示例中,所有类都可以访问strList。 i want have a list that all session can access to it (add or remove thing in that list). 我想要一个所有会话都可以访问的列表(在该列表中添加或删除内容)。

service configuration is buffered and none security . 服务配置被缓冲并且没有安全性。 and service attribute is here : 服务属性在这里:

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

EDIT : i dont want create that classes that was only one example. 编辑:我不想创建那只是一个例子的类。 i just need have a list that all session can access to it.when you have InstanceContextMode.PerSession service that service class will create per each client then each client have their own service class now i want each session that created can access one public list . 我只需要有一个列表,所有会话都可以访问它。当您拥有InstanceContextMode.PerSession服务时,该服务类将为每个客户端创建一个类,然后每个客户端都有自己的服务类。我希望创建的每个会话都可以访问一个公共列表。

EDIT2: this list is in server and just server can access it dont need send list to client. EDIT2:此列表在服务器中,只有服务器可以访问它,不需要将列表发送到客户端。 it is server variable for calculate some thing . 它是用于计算某些东西的服务器变量。

You can use a static property in your service class for example: 您可以在服务类中使用静态属性,例如:

[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 will create a new instance of MyService for each new client connecting to your service. WCF将为连接到您的服务的每个新客户端创建MyService的新实例。 They all have access to the static property. 它们都可以访问静态属性。

You would probably want your ConcurrencyMode set to Multiple, and you will need to ensure you treat your object as multithreaded, since that is what you are basically setting up. 您可能希望将ConcurrencyMode设置为Multiple,并且您将需要确保将对象视为多线程,因为这基本上是您要设置的。 There is a pattern to avoid deadlock in this situation that requires multiple locking. 在这种情况下,有一种避免死锁的模式,它需要多次锁定。 See This MSDN article for details . 有关详细信息,请参见此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");
    }
}
}

If you are looking at using a collection though, I would suggest looking at the Concurrency Collection objects, as these are made for multithreaded access. 如果您正在使用集合,那么我建议您查看并发集合对象,因为这些对象是为多线程访问而设计的。 Those objects take out the need for locking, as they have self contained locking, which is nice in the case you forget in the future. 这些对象不需要锁定,因为它们具有自包含的锁定,这在将来您忘记的情况下很好。

EDIT: Just to add for information, locking will block other threads from executing code in that lock or accessing a locked property. 编辑:只是为了提供信息,锁定将阻止其他线程执行该锁定中的代码或访问锁定的属性。 For this reason, it is not suggested to to lengthy opertions in a lock as it can slow down ALL clients. 因此,不建议长时间进行锁定操作,因为它会降低所有客户端的速度。 Additionally, your InstanceContextMode being set to PerCall will create a new instance of your service class for EVERY CALL to your service. 此外,将您的InstanceContextMode设置为PerCall将为您的服务每次调用创建服务类的新实例。 Inversly, if you don't have any activity and all your service instance get cleaned up or closed out, then you will also lose your shared object. 相反,如果您没有任何活动,并且所有服务实例都已清理或关闭,那么您还将丢失共享对象。

I think you should build a DataContract 我认为您应该建立一个DataContract

Example : 示例:

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

     class B
       {
       }

     class C
       {
       }
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM