C#-Parallel.Foreach()用于服务调用
我有一个控制台应用程序,它执行以下3个步骤C#-Parallel.Foreach()用于服务调用,c#,.net,console-application,parallel.foreach,.net-4.6.1,C#,.net,Console Application,Parallel.foreach,.net 4.6.1,我有一个控制台应用程序,它执行以下3个步骤 从数据库获取挂起的通知记录 呼叫服务发送电子邮件(服务返回电子邮件地址作为响应) 获得服务响应后,更新数据库 对于步骤2,我使用的是Parallel.Foreach(),它比Foreach()工作得好得多。 我已经阅读了很多关于stackoverflow的文章和帖子,这在这个主题上造成了更多的混乱。 我有几个问题 我在服务器上运行这个,它会影响性能吗?我应该限制线程的数量吗?(电子邮件计数可以是0-500或1000) 我遇到了一个问题,在步骤2中,服务
public void notificationMethod()
{
列表通知列表=新列表();
//第一步
List orderList=GetNotifs();
尝试
{
如果(orderList.Count>0)
{
Parallel.ForEach(orderList,(orderItem)=>
{
//步骤2
发送通知(订单项);
notifList.Add(新通知()
{
//通过添加电子邮件地址和其他信息建立列表
});
});
如果(notifList.Count>0)
{
int指数=0;
int行=10;
int skipRows=索引*行;
int updatedRows=0;
while(skipRows
关于使用Parallel.ForEach()
是否有助于提高性能,我也有类似的情况。但是,当我看到下面来自Microsoft的视频时,我想到了选择Parallel.ForEach()
仅用于CPU密集型工作负载。
在这种情况下,您的场景将属于I/O密集型工作负载,可以通过async
/wait
更好地处理
我认为您应该使用一种专门的并发收集类型(针对notifList),而不是列表,我会使用ConcurrentBag,看看这是否解决了问题。除了@StewartRitchie comment,我建议您也使用任务并行库。该库为您执行大部分线程管理,并且有多种方法可以捕获和处理每个请求的异常。没有直接涉及线程,因此通常使用起来也更安全。然后,可以使用
await foreach()
并行运行这些操作。有关详细信息。@NikP如果他们正在使用Parallel.ForEach
,他们已经在使用TPL了。您引用的是更具体的内容吗?@digitlworld是的,特别是在任务中包装单个调用,并使用TAP模式,并遵循异常处理建议和。要点是更好地控制在何处捕获异常以及如何处理异常,因此,如果1000个调用中有一个抛出,它不会破坏其余调用,您可以跟踪失败的调用以找出原因。要扩展@StewartRitchie提到的内容:List
不是线程安全的。如果多个线程同时添加项目,您肯定会丢失一些<代码>ConcurrentBag是线程安全的。
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)
{
}
}