Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-Parallel.Foreach()用于服务调用_C#_.net_Console Application_Parallel.foreach_.net 4.6.1 - Fatal编程技术网

C#-Parallel.Foreach()用于服务调用

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中,服务

我有一个控制台应用程序,它执行以下3个步骤

  • 从数据库获取挂起的通知记录
  • 呼叫服务发送电子邮件(服务返回电子邮件地址作为响应)
  • 获得服务响应后,更新数据库
  • 对于步骤2,我使用的是Parallel.Foreach(),它比Foreach()工作得好得多。 我已经阅读了很多关于stackoverflow的文章和帖子,这在这个主题上造成了更多的混乱。 我有几个问题

  • 我在服务器上运行这个,它会影响性能吗?我应该限制线程的数量吗?(电子邮件计数可以是0-500或1000)
  • 我遇到了一个问题,在步骤2中,服务返回了一个电子邮件地址作为响应,但在更新数据库时它不可用。(这里的电子邮件数量是400) 我怀疑这个问题可能是因为使用parallel.foreach而没有添加notifList。 如果是这种情况,我可以在Parallel.Foreach()循环结束后添加Thread.Sleep(1000)吗?它解决了这个问题吗
  • 如果出现任何异常,我是否应该显式取消线程
  • 感谢你花时间和精力来帮助我。谢谢大家!

    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)
        {
        }            
    }