并发集合与锁定列表

Concurrent Collection vs locking list

我正在尝试学习如何使用线程,但我坚持使用并发集合。

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

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

下一步我想实现的是另一种方法(例如,由用户使用按钮处理),它允许用户从第一个列表中选择任何对象并手动将其删除。 "problem" 我想模拟的是,如果对象正在被线程 "processed",用户不应该能够将它从列表中删除。

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

我考虑过使用字典,但我看不出为什么我应该使用带有键值参数的字典,而我只需要存储对象。

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

谢谢

Queues、Stacks 和 Bags 的好处是您在获得它之前不需要知道您得到的是哪个 object。在您的情况下,您确实知道要操纵哪个 object。

听起来你有一种混合模型,你有一个处理机制可以从 collection、'finishes' 中获取 'unfinished' objects,然后将它们放入 'finished' collection。 (看起来你正在使用列表。)你还有一个用户界面,允许用户从 'unfinished' collection 中选择任何给定的 object 并将其从 collection.

你的处理机制应该的工作方式是这样的:代码处理object应该

  • 从'unfinished'collection中移除一个object待处理。
  • 处理 object.
  • 将其放入 'finished' collection.
  • 重复。

也就是说,当前正在处理的 object 不应出现在 'unfinished' collection 中,因为它在处理之前已被删除。

现在,如果您想向用户显示 'unfinished' collection 中的项目,则需要遍历它们。您还需要为它们提供某种密钥,这样当用户单击其中一个时,您就可以分辨出是哪个。

执行此操作的一个好方法是序列号,您可以使用 Interlocked.Increment(ref staticSerialNumber) 增加序列号。

然后你可以使用 ConcurrentDictionary<int><yourObject> collection 作为你的 'unfinished' collection.

插入一个新的 object 很容易:

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

要在其中获取 object 的列表很容易。使用 dict.GetEnumerator() 方法。

要从字典中取出一个项目,您可以使用枚举器找到第一个项目,然后使用 TryRemove(key) 来完成。

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