【发布时间】:2012-01-07 03:55:11
【问题描述】:
我正在尝试以支持多线程和并发的方式转换现有进程,以使解决方案更加健壮和可靠。
以紧急警报系统为例。当工作人员签到时,将使用他们的信息创建一个新的收件人对象,并将其添加到收件人集合中。相反,当他们下班时,对象会被移除。在后台,当警报发生时,警报引擎将遍历相同的收件人列表 (foreach),对每个对象调用 SendAlert(...)。
这是我的一些要求:
- 如果正在进行警报,则不应阻止添加收件人。
- 如果正在进行警报,则不应阻止删除收件人。
- 添加或删除收件人不应影响收件人列表 正在进行的警报使用的收件人。
我一直在研究 Task 和 Parallel 类以及 BlockingCollection 和 ConcurrentQueue 类,但不清楚最好的方法是什么。
是否像使用 BlockingCollection 一样简单?在阅读了大量文档后,我仍然不确定如果在枚举集合时调用 Add 会发生什么。
更新
一位同事向我推荐了以下文章,该文章描述了 ConcurrentBag 类以及每个操作的行为方式:
http://www.codethinked.com/net-40-and-system_collections_concurrent_concurrentbag
根据作者的解释,这个集合似乎(几乎)可以达到我的目的。我可以做到以下几点:
-
创建一个新集合
var recipients = new ConcurrentBag();
-
当工作人员打卡时,创建一个新的收件人并将其添加到集合中:
recipients.Add(new Recipient());
-
当警报发生时,警报引擎可以在那时遍历集合,因为 GetEnumerator 使用集合项的快照。
foreach(收件人中的 var 收件人) 收件人.SendAlert(...);
-
当工作人员下班时,将收件人从集合中删除:
???
ConcurrentBag 不提供删除特定项目的方法。据我所知,没有一个并发课程。我错过了什么吗?除此之外,ConcurrentBag 可以满足我的一切需求。
【问题讨论】: