锁定的字典上的字典 Add() 异常

本文关键字:字典 异常 锁定 Add | 更新日期: 2023-09-27 17:56:41

我的代码抛出了一个参数异常,抱怨"已经添加了具有相同键的项目"。
我正在锁定抱怨的对象,所以我不知道如何在另一个线程上更新它。
WaypointIconDictionary是静态的。
这是代码

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);
}

锁定的字典上的字典 Add() 异常

不要锁定 WaypointIconDictionary,创建一个唯一目的是锁定的新对象,例如:

Object _locker = new Object();

然后锁定它:

lock (_locker)
{

还要检查WaypointIconDictionary的所有用法,并确保没有其他内容添加到其中。最好的办法是将WaypointIconDictionary包装在一个对象中,以便可以漏斗和锁定对它的所有调用。

查看您的示例,如果 WaypointIconDictionary 是静态的,您将不得不_locker设为静态。

另一种选择是使用 ConcurrentDictionary,然后使用 TryAdd() 方法。

这可能根本不是锁定问题:可能是您实际上尝试添加相同的密钥两次。

如果您绝对确定这是将新条目添加到字典的唯一位置,则此异常只能由以下原因引起:

  1. waypoint被另一个线程覆盖
  2. IconCache.LoadIcon有一个令人讨厌的副作用,导致此线程再次调用此方法。

单步执行代码或记录要添加的内容,以便了解发生了什么。