2012-08-05 43 views
1

假设有像由多线程访问的Hashtable.Synchronized()创建的Hashtable。并且键值对是Hashtable中的Guid和Object。 其中一个线程需要轮询该Hashtable,直到另一个线程将特定的Guid键添加到此列表中。多线程访问.net中的一个集合

以下是我的代码。

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

} 

我想知道这个循环是否可以结束。我怎么能知道轮询过程中改变的哈希表?谢谢

+0

不知道有没有这样的事情,但你可以创建自己的类,并使用SychronizationAttribute HTTP:// msdn.microsoft.com/en-us/library/system.runtime.remoting.contexts.synchronizationattribute(v=vs.100).aspx – 2012-08-05 15:20:01

+0

据我所知,在.NET中没有直接的平等 - 但是'联锁类提供了很多相同的功能,如交换等。 – vcsjones 2012-08-05 15:24:43

+0

嗨.all。谢谢你的意见 。我编辑了我的问题。 – 2012-08-05 15:39:33

回答

1

阅读和更重要的分配给参考在.NET中总是原子。

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


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

当另一个(只有一个作者允许)线程插入想要的值时会结束,是的。

在MSDN:Hashtable is thread safe for use by multiple reader threads and a single writing thread.

但是你的解决方案是非常低效的。繁忙循环可以消耗大量的CPU时间。在旧式收藏中存放(盒装)Guids也不完美。

+0

请阅读我的问题。谢谢。 – 2012-08-05 16:18:04

+0

希望为这种情况提供更好的解决方案。非常感谢。 – 2012-08-05 16:35:01

+0

阅读[this](http://blogs.msdn.com/b/ericlippert/archive/2003/11/03/a-parable.aspx),然后发布一个新问题。 – 2012-08-05 16:36:51

2

看看上concurrent collections,尤其是在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

+0

当我在方法中循环集合时,我如何知道ConcurrentBag被更改?谢谢 – 2012-08-05 16:22:32