我正在创建一个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?
顺便说一下,配置方法仅由一个人使用。
答案 0 :(得分:1)
使用InstanceContextMode
PerCall
,每次远程调用进入时,您都应该获得服务和字典的新实例(我假设它是Configuration()
或ScanReceived()
)。这不会在多个客户端之间共享configurationDictionary
。
使用ConcurrencyMode
Single
,您在任何时候都只有一个运行代码的线程。因此,任何并发问题都没有实际意义。
分享configurationDictionary
的两种方式:
private readonly static ConcurrentDictionary<...> ...
InstanceContextMode
,可能还有ConcurrencyMode
。如果您不希望每秒拨打数千个电话,我建议使用第一个选项。
MSDN提供了有关InstanceContextMode和instancing服务类的一些信息。
如果更改为InstanceContextMode.Single
和ConcurrencyMode.Multiple
,您可以立即执行多个线程,并且需要担心同步访问。
需要注意的主要事项是,当您查询/迭代字典时,其他人可能会对其进行修改。抓取字典的快照然后查询快照应该可以解决这个问题:
foreach (var x in configurationDictionary.ToArray())
{
....
}
或者,如果您正在使用LINQ:
var someResult = configurationDictionary.ToArray().Where(...).Select(...)