2015-02-11 71 views
1

我試圖學習如何使用線程和Im堅持併發集合。併發收集VS鎖定列表

我有應用程序,其中有對象和方法的列表unfinishedOBjectsList<MyObject>,對特定對象(如DoChange(MyObject對象))做了一些更改。之後,該對象從第一個列表中取出並插入finishedObjectsList<MyObject>

現在,我想運行使用線程的方法,該線程工作正常 - 每個線程都做了一些更改(更改次數較少,所以我添加了ThreadSleep()來模擬一些對象的更長處理) unfinishedOBjectsList,將它從unfinishedOBjectsList中移除並放入第二個列表中。

下一步我想實現的是,會有另一種方法(例如用戶使用按鈕處理),這將允許用戶從第一個列表中選擇任何對象並將其刪除爲manualy。我想模擬的「問題」是,如果對象正在被線程「處理」,用戶不應該能夠從列表中刪除它。

我試過ConcurrentQueue - 但問題是,使用隊列,我無法刪除特定的對象(使用類似Remove(MyObject)的東西,因爲我可以做與列表)。之後,我嘗試了ConcurrentBag和BlockingCollection,但問題是一樣的 - 我能夠刪除集合中的下一個對象,但不是集合中間的對象。

我曾考慮過使用字典,但我不能看到爲什麼我應該使用字典與鍵,值參數,而我只需要存儲對象的原因。

我的問題是 - 我應該甚至在這種情況下使用ConcurrentCollections?或者我應該簡單地鎖定列表並保持原樣?處理多訪問列表時,正確的方法是什麼?

謝謝

回答

1

隊列,棧,箱包有你不需要知道哪個對象你得到,直到你得到它的好處。在你的情況下,你確實知道你想操作哪個對象。

聽起來好像你有一種混合模型,你有一個處理機制,從一個集合中抓取未完成的對象,'完成'它們,然後將它們放入'已完成'集合中。 (看起來你在使用列表。)你也有一個用戶界面,允許用戶從'未完成'集合中選擇任何給定的對象並將其從該集合中取出。

的方式您處理機制應該工作是這樣的:碼處理對象應

  • 刪除要從「未完成」的收集處理的對象。
  • 處理對象。
  • 將它放入'已完成'集合中。
  • 重複。

也就是說,當前正在處理的對象不應出現在'未完成'集合中,因爲它在處理之前已被刪除。

現在,如果您想要將「未完成」集合中的項目顯示給用戶,則需要遍歷它們。你還需要給他們一些鍵,所以當用戶點擊其中一個鍵時,你就可以知道哪一個鍵。

一個很好的方法是使用Interlocked.Increment(ref staticSerialNumber)來增加序列號。

然後,您可以使用ConcurrentDictionary<int><yourObject>集合作爲「未完成」集合。

要插入一個新的對象變成很容易:

Interlocked.Increment(ref staticSerialNumber); 
dict.GetOrAdd(staticSerialNumber, newObject); 

要獲得對象的列表中很容易。使用dict.GetEnumerator()方法。

要從字典中獲取項目,可以使用枚舉數查找第一個項目,然後使用TryRemove(key)來完成此操作。

簡而言之,ConcurrentDictionary可能是您的應用程序的不錯選擇。

+0

這是很好的解釋,我不知道有像「聯鎖」之類的東西。我一定會用它並按照你的建議來實現它。感謝您的時間和幫助,我真的很感激。 – JakubJ 2015-02-12 08:19:51