并发收集与锁定列表

时间:2015-02-11 23:12:40

标签: c# multithreading collections concurrency

我试图学习如何使用线程,并且我坚持使用Concurrent Collections。

我有应用程序,其中我有对象的列表unfinishedOBjectsList<MyObject>和方法,它们对特定对象(类似于DoChange(MyObject对象))进行了一些更改。之后,该对象从第一个列表中获取并插入finishedObjectsList<MyObject>

现在,我想使用线程运行该方法,该方法运行正常 - 每个线程都做了一些更改(更改很小,所以我添加了ThreadSleep()以模拟对象的更长处理)在unfinishedOBjectsList中找到的特定对象,将其从unfinishedOBjectsList中删除并将其放在第二个列表中。

我想实现的下一步是会有另一种方法(例如用户使用按钮处理),这将允许用户从第一个列表中选择任何对象并手动删除它。 &#34;问题&#34;我想模拟的是,如果对象正在被处理&#34;通过线程,用户不应该从列表中删除它。

我尝试过ConcurrentQueue - 但问题是,使用Queue,我无法删除特定对象(使用类似Remove(MyObject)之类的东西,就像我可以用list做的那样)。之后,我尝试了ConcurrentBag和BlockingCollection,但问题是一样的 - 我能够删除集合中的下一个对象,但不能删除集合中间的对象。

我考虑过使用Dictionary,但是我无法理解为什么我应该使用Key,Value参数的字典,而我只需要存储该对象。

我的问题是 - 我是否应该在这种情况下使用ConcurrentCollections?或者我应该只是锁定列表并保持原样?处理多访问列表时,正确的方法是什么?

谢谢

1 个答案:

答案 0 :(得分:1)

队列,堆叠和行李箱的好处是,您不需要知道在获得之前您将获得哪些物品。在您的情况下,您确实知道要操纵哪个对象。

听起来你有一种混合模式,你有一个处理机制,可以抓住未完成的&#39;来自集合的对象,&#39;完成&#39;他们然后把它们放进一个完成的&#39;采集。 (看起来你正在使用列表。)你还有一个用户界面,允许用户从未完成的&#39;中选择任何给定的对象。收集并从该系列中取出。

您的处理机制 的工作方式是:代码处理对象应该

  • 从未完成的&#39;删除要处理的对象。集合。
  • 处理对象。
  • 将其放入已完成的&#39;集合。
  • 重复。

也就是说,当前正在处理的对象永远不会出现在未完成的对象中。集合,因为它在处理之前被删除了。

现在,如果您想要显示未完成的内容中的项目,请执行此操作。收集到您的用户,您需要迭代它们。您还需要为他们提供某种密钥,因此当用户点击其中一个密钥时,您将能够分辨出哪一个密钥。

执行此操作的一种好方法是使用Interlocked.Increment(ref staticSerialNumber)递增的序列号。

然后,您可以使用ConcurrentDictionary<int><yourObject>收藏品来收集未完成的&#39;集合。

将新对象插入其中很容易:

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

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

要从字典中获取项目,您可以使用枚举器查找第一项,然后使用TryRemove(key)来执行此操作。

简而言之,ConcurrentDictionary可能是您应用程序的不错选择。