I’m creating a WCF Service Library and I have a question regarding thread-safety consuming a method inside this library, here is the full implementation that I have until now.
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)
{
}
}
}
Imagine that I have a 10 values in my configurationDictionary and many people want to query this dictionary consuming ScanReceived method, are those 10 values be shared for each of the clients that request ScanReceived? Do I need to change my ServiceBehavior?
The Configuration method is only consumed by one person by the way.
With an
InstanceContextModeofPerCallyou should get a new instance of your service and your dictionary every time a remote call comes in (which I’m assuming will be eitherConfiguration()orScanReceived()). This won’t shareconfigurationDictionarybetween multiple clients.With a
ConcurrencyModeofSingleyou’ll only ever have a single thread running your code at any one time. So any issues of concurrency are moot.Two ways to share
configurationDictionary:private readonly static ConcurrentDictionary<...> ...InstanceContextMode, and possibly yourConcurrencyMode.I’d recommend the first option if you’re not expecting thousands of calls to your service per second.
MSDN has some information about InstanceContextMode and instancing of service classes.
If you change to
InstanceContextMode.SingleandConcurrencyMode.Multipleyou can get many threads executing at once and you will need to worry about synchronised access.The main thing to watch out for is that when you’re querying / iterating over your dictionary, someone else might modify it. Grabbing a snapshot of the dictionary and then querying the snapshot should get around that problem:
Or, if you’re using LINQ: