Reputation: 1062
I am designing a web service(wcf) that has some of the static dictionaries (ie. maintaining some states of the server and connected clients). The service is in single instance mode and multiple concurrency, as shown below.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
public class CalculatorService : ICalculatorConcurrency
{
...
}
There are various operations that reads and writes to this static variables. I have one class level lock object and the way I am trying to avoid locks is using that object whenever any operations try to access that particular static variables.
Did I handling the concurrency correctly, as shown below? There can be various instances of the client accessing the service, i.e.
The sample code looks like:
[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();
...
}
}
}
Is my code thread safe? Or, moreover Am I doing it correctly?
Upvotes: 0
Views: 135
Reputation: 13197
Since you're using just one resource (i.e lockObject
) deadlocks are impossible. To get a deadlock you need to have at least two resources.
Is my code thread safe?
If you are using Dictionary<,>
to avoid any concurrency problems every interaction with that dictionary should be wrapped by lock(lockObject){}
as you did. So, you code is thread safe.
Am I doing it correctly?
You are doing correctly but if you are using .Net 4
or newest you have more convenient option with thread safe ConcurrentDictionary<TKey,TValue>
. It was designed special for cases like your. The difference is in that you can forget about lock
blocks. It will not throw an exception when one caller iterates through the dictionary and the second caller changes the dictionary. ConcurrentDictionary<TKey,TValue>
implements the IDictionary<TKey,TValue>
and in addition, provides convenient methods like TryAdd
, TryUpdate
and other.
So, you definitely need to you use ConcurrentDictionary
if it is possible, since it makes code more cleaner.
Upvotes: 2