We have a very serious problem that's causing thousands of exceptions per minute. We've got a website that runs a home-grown caching mechanism that holds data in the form of:
protected static IDictionary<int, IList<IInterfaceForData>> m_Data = null;
and when we call Add on this dictionary, we get a very bizarre behavior: "Index was outside the bounds of the array", when the key was 100% not in the dictionary:
m_Data.Add(id, new List<IInterfaceForData>());
We protect this call using a lock like this:
if(Monitor.TryEnter(m_LockObj, 1000))
{
try
{
m_Data.Add(id, new List<IInterfaceForData>());
}
catch(Exception ex)
{
// log exception
}
finally
{
Monitor.Exit(m_LockObj);
}
}
and we get this exception:
at System.Collections.Generic.Dictionary`2.Resize() at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
We can't find any explanation for this because the exception is related to Dictionary's thread safety, and we (think we) are thread safe. We use lock() or Monitor.TryEnter on every Add() and Remove() calls, except for m_Data.TryGetValue(...)
Any help would be greatly appreciated.
thanks a lot.
It seems like at some point the code is not locked and the collection is changed... Have you taken a look at the System.Collections.Concurrent
namespace? Specifically the ConcurrentDictionary class? It is thread safe and will probably save you from lots of pains of weird bugs like that or race conditions, etc
It works almost like the regular dictionary , except that for most operations you use a "try" method ie TryGetValue
this will try to get the value and return True
if the operation was valid and False
if not, you can then of course check against this values to continue with your logic
You should check-out this msdn link, its really similar to what you are doing:
Implementing a cache with ConcurrentDictionary
the asker is currently using a non-concurrent dictionary with a ReaderWriterLockSlim
and is changing it to a concurrent dictionary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With