2008-09-02 79 views
3

我正在尋找一種在C#中獲取併發集合或至少支持併發枚舉器的集合的方法。現在,當我迭代的集合發生變化時,我得到一個InvalidOperationException異常。我可能只是深拷貝的收集和使用私人拷貝工作,但我不知道是否有可能是一個更好的辦法C#中的併發集合

代碼片段:

foreach (String s in (List<String>)callingForm.Invoke(callingForm.delegateGetKillStrings)) 
    { 
     //do some jazz 
    } 

- 編輯 -

我把答案還發現我需要確保寫入集合的代碼也需要嘗試鎖定。

private void addKillString(String s) 
    { 
     lock (killStrings) 
     { 
      killStrings.Add(s); 
     } 
    } 

回答

5

除了做深複製你最好的選擇可能是鎖定集合:

List<string> theList = (List<String>)callingForm.Invoke(callingForm.delegateGetKillStrings); 
    lock(theList.SyncRoot) { 
     foreach(string s in theList) { 
       // Do some Jazz 
     } 
    } 
4

所以我不太清楚你問什麼,但並行擴展團隊把一些可能符合法案的東西放在一起。特別是關於enumerating parallel collections的博客文章。它還包含下載並行CTP的鏈接,您當然可以瀏覽其他博客文章,以瞭解CTP的意圖和編程模型的工作原理。

1

如果您想使用FCL集合,那麼鎖定是支持可能重疊的多個線程進行迭代/修改的唯一方法。

不過要小心你用作鎖對象。如果集合本身是使用它的類的私有成員,則使用SyncRoot只是一個好主意。如果集合受保護或公開,那麼您的類的客戶端可能會在SyncRoot上佔用自己的鎖,這可能會導致類中的代碼發生死鎖。

如果您有興趣查看第三方收藏圖書館,我推薦優秀的C5 Generic Collection Library。他們擁有一系列基於樹的集合,可以輕鬆安全地修改和重複同時進行迭代,而無需鎖定 - 有關詳細信息,請參閱其優秀文檔的第8.10和第9.11節。