I have a problem adding a new item to a Static dictionary while using it from multiple threads. Any ideas where I'm doing it wrong?
Initializing the dictionary:
public static class Server
{
public static volatile Dictionary<int, List<SomeClass>> Values;
}
Trying to add an item:
Server.Values.Add(someInt, new List<SomeClass> { elements});
As explained by Jon Skeet you are using an object which is not guaranteed to be thread safe
try using ConcurrentDictionary which is designed for Concurrency Scenario With Many threads
public static class Server
{
public static ConcurrentDictionary<int, List<SomeClass>> Values =
new ConcurrentDictionary<int, List<SomeClass>>();
}
Here how to use it
bool added = Server.Values.TryAdd(someInt, new List<SomeClass> { elements});
In general, when working with resources that are shared between multiple threads, you need to use a synchronization mechanism, like lock() to make your code thread safe. Create a common object to use as the lock:
private object _lock = new object();
Then you surround any code which accesses your shared resource, like this:
lock(_lock)
{
// perform operations on shared resource here.
}
It's important to note that you should have a different lock for every shared resource rather than one lock used for all resources. If you use your lock object with multiple resources, your code could be very inefficient. If one thread grabs the lock so it can use resource A, then other threads will have to wait for the lock to be released even if they want to access resource B which has nothing to do with the resource A. Therefore, it's better to have one lock object per resource and to name your lock objects so you know which resources they should be used with.
An alternative to this (as BRAHIM Kamel's answer shows) is to use a replacement, if available, for your shared resource which already has thread synchronization baked in, like ConcurrentDictionary. Though this may not be feasible in your case.
Related
I am trying to implement a generic thread-safe Cache method, and I wonder how I should implement the lock in it.
It should look something like this:
//private static readonly lockObject = new Object();
public T GetCache<T>(string key, Func<T> valueFactory...)
{
// try to pull from cache here
lock (lockObject) // I don't want to use static object lock here because then every time a lock is performed, all cached objects in my site have to wait, regarding of the cache key.
{
// cache was empty before we got the lock, check again inside the lock
// cache is still empty, so retreive the value here
// store the value in the cache here
}
// return the cached value here
}
For non shared data among pools
When you have many pools (web garden) each pool can have their static data. There I have measure this days that the ConcurrentDictionary<TKey, TItem> is the faster because they have implement some kind of technique that don't use look inside, so they have make it extreme fast.
So I suggest the ConcurrentDictionary<TKey, TItem> for non shared data among pools.
In this case you must take care the synchronization of the data him self to avoid concurrent data change on the same the data. There you can use the SlimLock, or a Lock.
common resources change among pools
Now, when you have resource that are shared among pools, you need to use mutex. For example if you try to go to save a file from many threads, of open a file for change it from many threads - you need mutex to synchronize that common resource
So for common resource you use the mutex
Mutex can use a Key to lock to lock base on that key - but you can not change the same resource!.
public T GetCache<T>(string key, Func<T> valueFactory...)
{
// note here that I use the key as the name of the mutex
// also here you need to check that the key have no invalid charater
// to used as mutex name.
var mut = new Mutex(true, key);
try
{
// Wait until it is safe to enter.
mut.WaitOne();
// here you create your cache
}
finally
{
// Release the Mutex.
mut.ReleaseMutex();
}
}
What kind of lock
we have two case for lock.
One case is when we use common resources in all pools, all threads. Common resource can be a file, or the database its self.
In the common resources we need to use mutex.
Second case is when we use variables that are visible only to the inside of a pool - different pools can not see that resources. For example a static List<>, a static Dictionary etc. This static variables, arrays can access only inside the pool and they are not the same across different pools.
In this second case, the lock() is the most easy and common way to use.
Faster than lock
Now, when we have a static dictionary that we keep for long time and make too many reads/writes there, a faster approach to avoid the full program to wait, is the ReaderWriterLockSlim
you can take a full example from here: ReaderWriterLockSlim
Using the ReaderWriterLockSlim, we can avoid the locks when we do not need them - and we do not need to lock the static values when we read - only when we write on them. So I can suggest it for static values that we use them as cache.
What is a pool in asp.net.
Imaging as if different programs that run isolate each other but serves the incoming requests from users. Each pool have his own world and they are not communicate each other. Each pool have their initialize, their static values, and their life. To have some common resource between pools you need some other third program, like a database, like a file on disk, like a service.
So if you have many pools (web garden) to synchronize them for common resource you need mutex. To synchronize them inside you use lock.
IIS app pools, worker processes, app domains
Lifetime of ASP.NET Static Variable
I just found LazyCache lib. I haven't tried it yet in production though.
IAppCache cache = new CachingService();
ComplexObject cachedResults = cache.GetOrAdd("uniqueKey",
() => methodThatTakesTimeOrResources());
The .NET ConcurrentDictionary<TKey, TItem> implements this internally by creating a separate lock for each key hash. This has the benefit of only locking the one relevant hash, even when processing item additions and removals.
I have inherited some C# code that I need to do fine-tuning. Since the dictionary (in the following code) is created on stack meaning individual instance (created by different threads) will be used for each call and it is not necessary to use the lock in this case, is that correct? Looks to me, it is not necessary.
private object textLock = new object();
private Dictionary<string, string> GetMyTexts(Language language)
{
Dictionary<string, string> texts = new Dictionary<string, string>();
foreach (KeyValuePair<string, DisplayText> pair in Repository.DisplayTextCollection.Texts)
{
string value = pair.Value.Get(language);
//other code ....
lock(textLock)
{
texts.Add(pair.Key, value);
}
}
return texts;
}
For clarification, the dictionary is created on the heap - it's only the reference to the dictionary which lives on the stack.
Since no other thread or context has access to the reference until the method returns, no other code can simultaneously modify the dictionary, so the lock where it is currently is useless.
On the other hand, if the lock were outside the foreach loop, it might have been used to make sure only one of these methods is executing at any one time (for example, if Language or Repository was not thread safe)
Most likely you are correct and the lock is useless, but to remove any doubt that someone may have, let me ask you a question:
Isn't this part of
//other code ....
containing a call to a method or some code that can acquire both the textLock and the texts?
This would be the only case when some other thread could insert into texts while locking also the textLock. If that is not the case, then you can safely remove the textLock.
Since there is just one thread supposed to be accessing that dictionary, according to the MSDN that lock statement wouldn't be necessary.
The lock statement acquires the mutual-exclusion lock for a given object, executes a statement block, and then releases the lock. While a lock is held, the thread that holds the lock can again acquire and release the lock. Any other thread is blocked from acquiring the lock and waits until the lock is released.
I may be missing some blindingly obvious documentation somewhere, but is static readonly member variable guaranteed to be initialized properly for use as a lock object?
In short, I have a library class that performs operation on an external resource that should only have a single instance touching it at any one time (don't have to worry about another process, it's only on a single process). The library class itself can have multiple instances in multiple threads, so in order to ensure that only one instance access said resource at a time, I need to use a lock.
I've seen a lot of lock object declaration like this.
private static readonly object _lockObj = new object();
Can this guarantee that multiple threads won't, by bad timing, initialize the two objects at the same time and lock on two objects? Or should I be creating the lock object like this.
private static readonly Lazy<object> _lockObj = new Lazy<object>(() => new object());
P.S. I'm referring to the C#'s lock(_lockObj){...} keyword for locking.
The runtime guarantees only one copy of a static member field. You can even use it without any instances of the class. It would be safe for use as a lock object.
I have a class that maintains a static dictionary of cached lookup results from my domain controller - users' given names and e-mails.
My code looks something like:
private static Dictionary<string, string> emailCache = new Dictionary<string, string>();
protected string GetUserEmail(string accountName)
{
if (emailCache.ContainsKey(accountName))
{
return(emailCache[accountName]);
}
lock(/* something */)
{
if (emailCache.ContainsKey(accountName))
{
return(emailCache[accountName]);
}
var email = GetEmailFromActiveDirectory(accountName);
emailCache.Add(accountName, email);
return(email);
}
}
Is the lock required? I assume so since multiple requests could be performing lookups simultaneously and end up trying to insert the same key into the same static dictionary.
If the lock is required, do I need to create a dedicated static object instance to use as the lock token, or is it safe to use the actual dictionary instance as the lock token?
Collections in .NET are not thread safe so the lock is indeed required. An alternative to using the dictionary one could use Concurrent dictionaries introduced in .NET 4.0
http://msdn.microsoft.com/en-us/library/dd287191.aspx
Yes, the lock is required as long as code on other threads can/will access the static object.
Yes, its safe to lock on the dictionary itself, as long as its not accessible via a public getter. Then the caller might use the object for locking itself and that might result in deadlocks. So i would recommend to use a separate object to lock in if your dictionary is somewhat public.
The lock is indeed required.
By using lock, you ensure that only one thread can access the critical section at one time, so an additional static object is not needed.
You can lock on the dictionary object itself, but I would simply use a object lock =new object(); as my lock.
MSDN documentation specify that you should never use the lock() statement over a public object that can be read or modified outside your own code.
I would rather use an object instance rather than the object you attempt to modify, specifically if this dictionnary has accessors that allows external code to access it.
I might be wrong here, I didn't write a line of C# since one year ago.
Since the dictionary is private, you should be safe to lock on it. The danger with locking (that I'm aware of) is that other code that you're not considering now could also lock on the object and potentially lead to a deadlock. With a private dictionary, this isn't an issue.
Frankly, I think you could eliminate the lock by just changing your code to not call the dictionary Add method, instead using the property set statement. Then I don't believe the lock at all.
UPDATE: The following is a block of code from the private Insert method on Dictionary, which is called by both the Item setter and the Add method. Note that when called from the item setter, the "add" variable is set to false and when called from the Add method, the "add" variable is set to true:
if (add)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
}
So it seems to me that if you're not concerned about overwriting values in your dictionary (which you wouldn't be in this case) then using the property setter without locking should be sufficient.
As far as I could see, additional object as a mutex was used:
private static object mutex = new object();
protected string GetUserEmail(string accountName)
{
lock (mutex)
{
// access the dictionary
}
}
If I have multiple threads calling the Add method of a List object, and no readers, do I only need to lock on the List object before calling Add to be thread safe?
Usually it's best to lock on a separate (immutable) object... locking on the same object you're modifying is bad practice should be done with caution.
private readonly object sync = new object();
private List<object> list = new List<object>();
void MultiThreadedMethod(object val)
{
lock(sync)
{
list.Add(val);
}
}
In a basic case like this you will not have a problem, but if there is a possibility that your list can be changed (not the contents of the list, but the list itself), then you might have a situation where you lock on two objects when you only intend to lock on one.
Yes. But you might also consider subclassing the List and "new" over the Add method. That will allow you to encapsulate the lock. It will work great as long as nothing accesses the base List. This technique is used for simple tree structures in XNA video games.
Yes, you need to lock. Instance methods are not guaranteed to be thread safe on List<T>.
I think these have been linked before on here, but I found them to be very useful and interesting:
Thread safe collections are hard
Thread safe collection