处理多线程并发服务问题

问题描述 投票:0回答:1

我设计的是有一些静态辞典的Web服务(WCF)(即维护服务器和连接的客户端的一些州)。该服务是在单一实例模式和多个并发性,如下所示。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]   
public class CalculatorService : ICalculatorConcurrency   
{   
    ...  
}  

有读取和写入该静态变量的各种操作。我有一个一流水平的锁定对象,我尽量避免锁是使用对象,只要任何操作试图访问特定的静态变量的方式。

难道我正确处理并发性,如下图所示?可以有访问服务的客户端的各种情况下,即

  • 客户端1使用该服务来修改()字典
  • 客户端2使用该服务以清除()字典
  • Client3使用该服务阅读()字典

示例代码是这样的:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
    public class CalculatorService : ICalculatorConcurrency
    {   
        private static int clientId;
        private static object lockObject = new object();
        private static Dictionary<int, Number> numberList = new Dictionary<int, Number>();


    public static Number ReadNumber(int n)
    {
        Number info;
        lock (lockObject)
        {
            if (!numberList.TryGetValue(n, out info))
            ...
        }
    }

    public static bool Modify(Number number)
    {
        lock (lockObject)
        {
            ...
        }
    }

    public bool Clear()
    {
        lock (lockObject)
        {
            numberList.Clear();
            ...
        }               
    }
}

是我的代码线程安全的?或者,而且我是不是做正确吗?

multithreading wcf concurrency locking deadlock
1个回答
2
投票

由于您使用的只是一个资源(即lockObject)死锁是不可能的。为了得到你需要有至少两个资源死锁。

是我的代码线程安全的?

如果您正在使用Dictionary<,>,以避免任何并发问题与字典的每一次互动应该lock(lockObject){}像你一样被包裹。所以,你的代码是线程安全的。

我在做正确吗?

你是做正确,但如果您使用的是.Net 4或最新的你有线程安全的ConcurrentDictionary<TKey,TValue>更方便的选择。它是为像你的情况而设计的专用。所不同的是,你可以约lock块算了。当通过字典一个呼叫者迭代和第二呼叫者改变字典它不会抛出异常。 ConcurrentDictionary<TKey,TValue>实现IDictionary<TKey,TValue>并且此外,提供了方便的方法,如TryAddTryUpdate等。

所以,你一定要使用ConcurrentDictionary,如果它是可能的,因为它使代码更干净。

© www.soinside.com 2019 - 2024. All rights reserved.