【发布时间】:2012-11-10 02:31:39
【问题描述】:
我正在尝试从多个线程添加到哈希集。如果该项目已经存在,我想更新它,如果它不存在,我想将它添加到列表中。
我使用的代码最终会出现很多重复项,我推测是因为多个项目突然指向同一个引用。但我看不出发生这种情况的地点或原因。
下面是我第一次看到问题时使用的代码,后面是“Log”字符串结尾。您可以看到突然间所有已添加的项目都具有相同的值。
lock (_remoteDevicesLock)
{
RemoteDevice rDevice = new RemoteDevice(notifyMessage.UUID, notifyMessage.Location);
log += notifyMessage.UUID + " " + rDevice.UUID;
if (!_remoteDevices.Add(rDevice))
{
log += " Not Added \r\n";
rDevice = (from d in _remoteDevices
where d.UUID.Trim().Equals(notifyMessage.UUID.Trim(), StringComparison.OrdinalIgnoreCase)
select d).FirstOrDefault();
if (rDevice != null)
{
//Update Device Expire Time
}
}
else
{
log += " Added \r\n Current HashSet: \r\n";
foreach (RemoteDevice rd in _remoteDevices)
{
log += rd.UUID + " \r\n";
}
}
}
00000000-0000-0001-1000-001cdf885737 00000000-0000-0001-1000-001cdf885737 Added
Current HashSet:
00000000-0000-0001-1000-001cdf885737
00000000-0000-0001-1000-001cdf885737 00000000-0000-0001-1000-001cdf885737 Not Added
00000000-0000-0001-1000-001cdf885737 00000000-0000-0001-1000-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Added
Current HashSet:
00000000-0000-0001-1000-001cdf885737
00000000-0000-0001-0002-001cdf885737
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0001-001cdf885737 00000000-0000-0001-0001-001cdf885737 Added
Current HashSet:
00000000-0000-0001-1000-001cdf885737
00000000-0000-0001-0002-001cdf885737
00000000-0000-0001-0001-001cdf885737
00000000-0000-0001-0001-001cdf885737 00000000-0000-0001-0001-001cdf885737 Not Added
00000000-0000-0001-0001-001cdf885737 00000000-0000-0001-0001-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Added
Current HashSet:
00000000-0000-0001-1000-001cdf885737
00000000-0000-0001-0002-001cdf885737
00000000-0000-0001-0001-001cdf885737
00000000-0000-0001-0000-001cdf885737
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-1000-001cdf885737 00000000-0000-0001-1000-001cdf885737 Not Added
00000000-0000-0001-1000-001cdf885737 00000000-0000-0001-1000-001cdf885737 Not Added
00000000-0000-0001-1000-001cdf885737 00000000-0000-0001-1000-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0001-001cdf885737 00000000-0000-0001-0001-001cdf885737 Not Added
00000000-0000-0001-0001-001cdf885737 00000000-0000-0001-0001-001cdf885737 Not Added
00000000-0000-0001-0001-001cdf885737 00000000-0000-0001-0001-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-1000-001cdf885737 00000000-0000-0001-1000-001cdf885737 Not Added
00000000-0000-0001-1000-001cdf885737 00000000-0000-0001-1000-001cdf885737 Not Added
00000000-0000-0001-1000-001cdf885737 00000000-0000-0001-1000-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0002-001cdf885737 00000000-0000-0001-0002-001cdf885737 Not Added
00000000-0000-0001-0001-001cdf885737 00000000-0000-0001-0001-001cdf885737 Not Added
00000000-0000-0001-0001-001cdf885737 00000000-0000-0001-0001-001cdf885737 Not Added
00000000-0000-0001-0001-001cdf885737 00000000-0000-0001-0001-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-0000-001cdf885737 00000000-0000-0001-0000-001cdf885737 Not Added
00000000-0000-0001-1000-001cdf885737 00000000-0000-0001-1000-001cdf885737 Added
Current HashSet:
00000000-0000-0001-0000-001cdf885737
00000000-0000-0001-0000-001cdf885737
00000000-0000-0001-0000-001cdf885737
00000000-0000-0001-0000-001cdf885737
00000000-0000-0001-1000-001cdf885737
更新:这里是 GetHashCode And Equals As Requested,尽管我认为问题不在于这里,因为我使用的是带有手动检查的列表并且也有问题。
public override bool Equals(object obj)
{
var other = obj as RemoteDevice;
if (other == null)
{
return false;
}
else
{
return UUID.Trim().Equals(other.UUID.Trim(), StringComparison.OrdinalIgnoreCase);
}
}
public override int GetHashCode()
{
return UUID.GetHashCode();
}
【问题讨论】:
-
1.不要锁定暴露在课堂之外的对象;您可能应该创建一个特定的对象只是为了锁定。 2.不要使用字符串连接添加到日志字符串,使用
StringBuilder。 -
RemoteDevice.Equals 和 RemoteDevice.GetHashCode 是什么样的?
-
@Servy 我如何保护哈希集不被添加和删除。哈希集在类外读取但未修改。 2)“日志”只针对这个问题。
-
您是否在检索到哈希集中的条目后更新它们的 UUID?如果不是,您如何解释日志中现有条目的 id 的变化?