假设有一些类似Hashtable由Hashtable.Synchronized()创建的,它由多个线程访问。密钥值对是Hashtable中的Guid和Object。 其中一个线程需要轮询此Hashtable,直到另一个线程将特定的Guid键添加到此列表中。
以下是我的代码。
public Hashtable syncHt = new Hashtable();
public void Init()
{
Hashtable ht = new Hashtable();
syncHt = Hashtable.Synchronized(ht);
}
在应用程序初始化中,我将调用init();
在一个线程中,我将调用isExist来查找由其他线程添加的特定Guid。
public bool isExist(Guid sId)
{
while (true)
{
if (syncHt.ContainsKey(sId))
{
return true;
}
}
}
我想知道这个循环是否可以结束。如何知道轮询期间Hashtable的变化?谢谢
答案 0 :(得分:2)
查看concurrent collections,尤其是ConcurrentBag<T>
<强>更新强>
关于IsExist,这是更好的解决方案
更改Hashtable
上的ConcurrentDictionary<Guid, object>
,因此无需锁定
将项目添加到repository
,无需任何锁定
ConcurrentDictionary<Guid, object> repository = new ConcurrentDictionary<Guid, object>();
检查存储库中的现有项目
public bool IsExist(Guid id)
{
SpinWait.SpinUntil(() => repository.ContainsKey(id)); - you can add Timout
return true;
}
以下是SpinWait
的更多信息答案 1 :(得分:1)
读取和更重要的引用分配在.NET中始终是原子的。
要进行原子操作,请使用System.Threading.Interlocked
类。见MSDN
我想知道这个循环是否可以结束。
当另一个(只允许1个编写者)线程插入所需值时,它将结束,是的。
在MSDN上:Hashtable is thread safe for use by multiple reader threads and a single writing thread.
但是你的解决方案效率很低。繁忙的循环可以消耗大量的CPU时间。存储(盒装)旧式集合中的Guids也不完美。