C# - 用于服务调用的 Parallel.Foreach()
Posted
技术标签:
【中文标题】C# - 用于服务调用的 Parallel.Foreach()【英文标题】:C# - Parallel.Foreach() for Service Call 【发布时间】:2020-09-05 17:15:39 【问题描述】:我有一个控制台应用程序,它执行下面提到的 3 个步骤,
-
从 db 获取待处理的通知记录
调用服务发送电子邮件(服务返回电子邮件地址作为响应)
得到服务响应后,更新数据库
对于第 2 步,我使用的是 Parallel.Foreach(),它的效果比 foreach() 好得多。 我已经阅读了很多关于 *** 的文章和线程,这在这个主题上造成了更多的混乱。 我有几个问题
-
我在服务器上运行它,它会影响性能吗?我应该限制线程数吗? (电子邮件数量可以是 0-500 或 1000)
我遇到了一个问题,在第 2 步中,服务返回了一个电子邮件地址作为响应,但在更新数据库时它不可用。 (这里的电子邮件数量是 400)
我怀疑这个问题可能是因为使用了 parallel.foreach 并且它没有添加到 notifList 中。
如果是这种情况,我可以在 Parallel.Foreach() 循环结束后添加 Thread.Sleep(1000),是否可以解决问题?
万一出现异常,我应该明确取消线程吗?
感谢您花时间和精力帮助我。谢谢!
public void notificationMethod()
List<notify> notifList = new List<notify>();
//step 1
List<orders> orderList = GetNotifs();
try
if (orderList.Count > 0)
Parallel.ForEach(orderList, (orderItem) =>
//step 2
SendNotifs(orderItem);
notifList.Add(new notify()
//building list by adding email address along with other information
);
);
if (notifList.Count > 0)
int index = 0;
int rows = 10;
int skipRows = index * rows;
int updatedRows = 0;
while (skipRows < notifList.Count)
//pagination
List<notify> subitem = notifList.Skip(index * rows).Take(rows).ToList<notify>();
updatedRows += subitem.Count;
//step 3
UpdateDatabase(subitem);
index++;
skipRows = index * rows;
catch (ApplicationException ex)
【问题讨论】:
我认为您应该使用一种专门的并发集合类型(用于 notifList),而不是 Listawait foreach()
并行运行这些。 Review the docs here 了解更多详情。
@NikP 如果他们正在使用Parallel.ForEach
,他们已经在使用 TPL。您引用的内容是否更具体?
@digitlworld 是的,专门将单个调用包装在任务中并使用 TAP 模式,并遵循异常处理建议 here 和 here。要点是更好地控制在何处捕获哪些异常以及如何处理它们,因此如果 1000 个调用中的一个抛出,它不会弄乱其余的,您可以跟踪失败的调用以找出原因。
扩展@StewartRitchie 提到的内容:List<T>
不是线程安全的。如果多个线程同时添加项目,您肯定会丢失一些。 ConcurrentBag<T>
是线程安全的。
【参考方案1】:
关于使用Parallel.ForEach()
是否有助于提高性能,我也有类似的情况。但是当我看到下面来自 Microsoft 的视频时,它让我想到了为 CPU 密集型工作负载选择 Parallel.ForEach()
only。
在这种情况下,您的场景将属于 I/O 密集型工作负载,async
/await
可以更好地处理。
https://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Tip-2-Distinguish-CPU-Bound-work-from-IO-bound-work
【讨论】:
以上是关于C# - 用于服务调用的 Parallel.Foreach()的主要内容,如果未能解决你的问题,请参考以下文章