4
votes

I have the following code, and somehow yesterday evening it had thrown a lot of exceptions:

Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.IndexOutOfRangeException: Index was outside the bounds of the array. at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)

I just don't see how this is possible, I check for null and if the key is available. This is the only method where lastTimeoutCheck is used.

private static Dictionary<string, DateTime> lastTimeoutCheck;
private static readonly object CacheLock = new object();
private static void CheckTimeout(string groupName)
{
    if (lastTimeoutCheck == null)
    {
        lastTimeoutCheck = new Dictionary<string, DateTime>();
        return;
    }
    if (!lastTimeoutCheck.ContainsKey(groupName))
    {
        lastTimeoutCheck.Add(groupName, DateTime.UtcNow);
        return;
    }

    if (lastTimeoutCheck[groupName] <
        DateTime.UtcNow.AddMinutes(-GroupConfigSection.TimeOutCheckMinutes))
    {
        lock (CheckLock)
        {
            if (lastTimeoutCheck[groupName] <
                DateTime.UtcNow.AddMinutes(-GroupConfigSection.TimeOutCheckMinutes))
            {
                GroupHolder groupHolder =
                    (GroupHolder) System.Web.HttpContext.Current.Cache.Get(groupName);
                if (groupHolder != null)
                {
                    groupHolder.UpdateTime();
                }

                lastTimeoutCheck[groupName] = DateTime.UtcNow;
            }
        }
    }
}
1
Are you using this method from multiple threads? Dictionary<,> is not thread-safe.Jon Skeet
If you look at the error message, you'll see that the error is happening at Dictionary<Tkey, Tvalue>.Insert(). Are you sure that groupName has a valid value?JLRishe
@JonSkeet I don't use any threading.BvdVen
@BvdVen then why locking on CheckLock ?Guillaume
the code executed while an other user is already running the code So you have multiple threads !Guillaume

1 Answers

4
votes

Since your variable is static and the error indicates it runs on a web server, you are most likely facing the problem that two threads access the same value at the same time, resulting in two adds at the same time.

The solution depends on your situation:

  1. Don't make the dictionary static, if you don't intend it to be shared across sessions. This doesn't really fix the problem. It makes it more unlikely to occur;
  2. Use a thread safe dictionary type: ConcurrentDictionary.