Question

My code is throwing an Argument Exception, complaining about "An item with the same key has already been added."
I am locking on the object that complains, so I don't know how it is possible for it to be updated on another thread.
The WaypointIconDictionary is static.
Here is the code

try
{
    lock (WaypointIconDictionary)
    {
        if (!WaypointIconDictionary.ContainsKey(waypoint.TypeOfWaypoint))
        {
            var thisIcon = waypoint.Icon;
            var index = IconCache.LoadIcon(thisIcon, thisIcon.Width / 2, thisIcon.Height);
            WaypointIconDictionary.Add(waypoint.TypeOfWaypoint, index);
        }
        IconCache.DrawIcon(graphics, x, y, WaypointIconDictionary[waypoint.TypeOfWaypoint], false);
    }
}
catch (Exception ex)
{
    Logger.Error("Waypoint drawing {0}", ex.Message);
}
Was it helpful?

Solution 2

This might not be a locking issue at all: it might be that you are actually trying to add the same key twice.

If you are absolutely sure that this is the only place where new entries are added to the dictionary, this exception could only be caused by:

  1. waypoint being overwritten by another thread
  2. IconCache.LoadIcon having a nasty side-effect that causes this thread to call this method again.

Step through the code or log what you are adding so you know what is going on.

OTHER TIPS

Don't lock WaypointIconDictionary, create a new object with the sole purpose of locking, such as:

Object _locker = new Object();

And then lock on that:

lock (_locker)
{

Also check for all usages of WaypointIconDictionary and make sure nothing else is adding to it. Best bet is to wrap WaypointIconDictionary in an object so that all calls to it can be funneled and locked.

Looking at your sample, if WaypointIconDictionary is static you are going to have to make _locker static.

Another option is to use a ConcurrentDictionary and then use the TryAdd() method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top