共享字典的WCF方法

时间:2011-10-18 23:46:21

标签: c# .net wcf web-services thread-safety

我正在创建一个WCF服务库,我有一个关于线程安全消耗这个库中的方法的问题,这是我到目前为止的完整实现。

namespace WCFConfiguration
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
    public class ConfigurationService : IConfigurationService
    {
        ConcurrentDictionary<Tuple<string,string>, string> configurationDictionary = new ConcurrentDictionary<Tuple<string,string>, string>();

        public void Configuration(IEnumerable<Configuration> configurationSet)
        {
            Tuple<string, string> lookupStrings;
            foreach (var config in configurationSet)
            {
                lookupStrings = new Tuple<string, string>(config.BoxType, config.Size);
                configurationDictionary.TryAdd(lookupStrings, config.RowNumber);
            }
        }

        public void ScanReceived(string boxType, string size, string packerId = null)
        {

        }
    }
}

想象一下,我的configurationDictionary中有10个值,很多人想查询这个使用ScanReceived方法的字典,是否为请求ScanReceived的每个客户端共享了10个值?我是否需要更改ServiceBehavior?

顺便说一下,配置方法仅由一个人使用。

1 个答案:

答案 0 :(得分:1)

使用InstanceContextMode PerCall,每次远程调用进入时,您都应该获得服务和字典的新实例(我假设它是Configuration()ScanReceived())。这不会在多个客户端之间共享configurationDictionary

使用ConcurrencyMode Single,您在任何时候都只有一个运行代码的线程。因此,任何并发问题都没有实际意义。

分享configurationDictionary的两种方式:

  1. 将其设为静态:private readonly static ConcurrentDictionary<...> ...
  2. 更改您的InstanceContextMode,可能还有ConcurrencyMode
  3. 如果您不希望每秒拨打数千个电话,我建议使用第一个选项。

    MSDN提供了有关InstanceContextModeinstancing服务类的一些信息。


    如果更改为InstanceContextMode.SingleConcurrencyMode.Multiple,您可以立即执行多个线程,并且需要担心同步访问。

    需要注意的主要事项是,当您查询/迭代字典时,其他人可能会对其进行修改。抓取字典的快照然后查询快照应该可以解决这个问题:

    foreach (var x in configurationDictionary.ToArray())
    {
         ....
    }
    

    或者,如果您正在使用LINQ:

    var someResult = configurationDictionary.ToArray().Where(...).Select(...)