2012-08-05 72 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