0

我是 WCF 中状态/并发管理的初学者。假设我有一个如下服务类:

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
        public class Service1 : IService1
        {
            private int _myCounter;
            private MyType _myType;
            private static MyType _myTypeStatic;
            private static Dictionary<string,string> _d = new Dictionary<string,string>();


            public void Method1()
            {
                // logic to set _myType
                // logic to set _myCounter

                // logic to set _myTypeStatic
                // logic to set _d

            }
            public void Method2()
            {
                // logic to save _myType, set in Method1() to db
                // logic to save _myCounter, set in Method1() to db

                // logic to save _myTypeStatic, set in Method1() to db
                // logic to save _d, set in Method1() to db    
            }
        }

如果 2 个客户端连接同时使用此服务,它们将在 2 个不同的线程上运行。由于只有服务实例,在这种情况下 2 个全局类级别变量的状态将如何变化?它如何用于静态变量和类型?这 2 个线程是否有可能拥有 2 个不同的变量数据副本,但仍使用一个服务实例?

4

2 回答 2

0

也许定义一个类或结构来存储变量集,然后简单地在方法中传递它?

public class Storage
{
    public Storage(int myCounter, MyType myType)
    {
        _myCounter = myCounter;
        _myType = myType;
    }
    public int _myCounter;
    public MyType _myType;
}

...

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Service1 : IService1
{
    public void Method1(Storage st)
    {
        // logic to set _myType
        // logic to set _myCounter
    }
    public void Method2(Storage st)
    {
        // logic to save _myType, set in Method1() to db
        // logic to save _myCounter, set in Method1() to db
    }
}

通过这种方式,Service1 可以处理它不直接连接到的数据——然而,每个调用者都必须“照顾”它的数据,例如在某处保存 Storage st。

于 2012-10-26T08:23:18.233 回答
0

首先,所有变量都应该是线程安全的关键部分。即使您没有设置 InstanceContextMode.Single,静态变量也将在所有实例之间共享。类变量将为进入该实例的所有线程共享。ConcurrencyMode.Multiple 表示可以进入多个线程。此外,即使您应用了关键部分,那么您使用的逻辑也将不起作用。如果然后线程设置数据并返回释放临界区。在它尝试进行另一个调用以保存数据之前,另一个线程可以覆盖数据。这意味着您需要在一次操作中存储数据。或者您想将数据设置一段时间然后将其存储,那么您可以将数据存储在哈希表中。就像在方法1中一样,使用关键部分来设置数据,并放置一个唯一的密钥来为客户端 ID 等数据设置密钥,如果客户端不知道,则将密钥返回给客户端。然后在方法 2 中,客户端将传递密钥。使用密钥访问哈希表并使用客户端检索数据并保存。

于 2012-10-26T08:33:02.770 回答