1

假设有由 Hashtable.Synchronized() 创建的类似 Hashtable 的东西,它可以被多个线程访问。键值对是 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;
            }
        }

}

我想知道这个循环是否可以结束。我怎么知道在轮询期间哈希表发生了变化?谢谢

4

2 回答 2

2

看看并发集合,尤其是ConcurrentBag<T>

更新

关于 IsExist,这里有更好的解决方案

改变所以不需要HashtableConcurrentDictionary<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的更多信息

于 2012-08-05T16:18:06.107 回答
1

在 .NET 中,读取和更重要的分配给引用始终是原子操作。

要进行原子操作,请使用System.Threading.Interlocked类。见MSDN


我想知道这个循环是否可以结束。

当另一个(仅允许 1 个写入器)线程插入想要的值时,它将结束,是的。

在 MSDN 上: Hashtable 是线程安全的,可供多个读取线程和单个写入线程使用。

但是您的解决方案非常低效。繁忙循环可能会消耗大量 CPU 时间。在旧式集合中存储(盒装)指南也不完美。

于 2012-08-05T15:39:25.457 回答