C# 使用并行Foreach时,多线程未按预期工作 public void gettorequest() { DataTable dtListofTransaction=新DataTable(); 字符串sconnection=ConfigurationManager.AppSettings[ConfigurationManager.AppSettings[“BUToProcess”].ToString()].ToString(); string query=“从MES中选择错误\u计数器、MembershipEnrollmentStatus\u ID\u PKID、出站\u xml、\u事务类型、ProcessSet\u GUID,其中TP=0和RS='A',以及\u事务类型='Initial Enrollment'; 使用(SqlConnection sqlConn=newsqlconnection(sconnection)) { sqlConn.Open(); 使用(SqlCommand cmd=newsqlcommand(查询,sqlConn)) { dtListofTransaction.Load(cmd.ExecuteReader()); var tmpdtListofTransaction=dtlistofttransaction; if(dtListofTransaction.Rows.Count>0) { var distinctlistofmilies=(来自tmpdtListofTransaction.AsEnumerable()中的行) 选择row.Field(“ProcessSet_GUID”).Distinct().ToList(); int countOfFamilies=distinctListOfFamilies.Count(); int FamiliesToBeProcessedByThread=(countOfFamilies>50?(countOfFamilies/Convert.ToInt32(ConfigurationManager.AppSettings[“ThreadsToUse”]))+1:countOfFamilies); var ListofSubscriberList=拆分列表(distinctListOfFamilies,FamiliesTobeProcessedByRead); var tmplistOfSubscriberLists=订阅列表; 如果(countofffamilies>0) { ForEach(订阅列表,新的并行选项{MaxDegreeOfParallelism=4},ac=> { foreach(ac中的变量guid) { Console.WriteLine(guid+“:”+DateTime.Now.ToString(“MM/dd/yyyy hh:MM:ss.fff”); var dbMembersToProcess=tmpdtListofTransaction.AsEnumerable()。其中(p=>object.Equals(p[“ProcessSet\u GUID”],GUID)&&p[“outbound\u xml”!=null); foreach(dbMembersToProcess中的var成员) { PushWWRequest.SendTransactions(成员[“outbound_xml”].ToString(),成员[“type_of_transaction”].ToString(),成员[“MembershipEnrollmentStatus_ID_PKID”].ToString(),Convert.ToInt32(成员[“Error_Counter”].ToString()); } } }); } } } sqlConn.Close(); } } 公共静态void SendTransactions(string sRequest,string sTransactionType,string sPKID=“”,int ErrorCounter=0) { 开关(绞线式) { 案例TransactionType.INITIALENROLLMENT: 尝试 { CMInitialCustomerSetupTypeClient svcInitialCustomerSetupClientProxy=ClientOrbProxy(); CMInitialCustomerSetupInitialCustomerSetupRequest=反序列化(sRequest); svcInitialCustomerSetupClientProxy.CMInitialCustomerSetup(initialCustomerSetupRequest); } 捕获(System.ServiceModel.CommunicationException svcexpt) { 打印SVCExpt } 打破 } }

C# 使用并行Foreach时,多线程未按预期工作 public void gettorequest() { DataTable dtListofTransaction=新DataTable(); 字符串sconnection=ConfigurationManager.AppSettings[ConfigurationManager.AppSettings[“BUToProcess”].ToString()].ToString(); string query=“从MES中选择错误\u计数器、MembershipEnrollmentStatus\u ID\u PKID、出站\u xml、\u事务类型、ProcessSet\u GUID,其中TP=0和RS='A',以及\u事务类型='Initial Enrollment'; 使用(SqlConnection sqlConn=newsqlconnection(sconnection)) { sqlConn.Open(); 使用(SqlCommand cmd=newsqlcommand(查询,sqlConn)) { dtListofTransaction.Load(cmd.ExecuteReader()); var tmpdtListofTransaction=dtlistofttransaction; if(dtListofTransaction.Rows.Count>0) { var distinctlistofmilies=(来自tmpdtListofTransaction.AsEnumerable()中的行) 选择row.Field(“ProcessSet_GUID”).Distinct().ToList(); int countOfFamilies=distinctListOfFamilies.Count(); int FamiliesToBeProcessedByThread=(countOfFamilies>50?(countOfFamilies/Convert.ToInt32(ConfigurationManager.AppSettings[“ThreadsToUse”]))+1:countOfFamilies); var ListofSubscriberList=拆分列表(distinctListOfFamilies,FamiliesTobeProcessedByRead); var tmplistOfSubscriberLists=订阅列表; 如果(countofffamilies>0) { ForEach(订阅列表,新的并行选项{MaxDegreeOfParallelism=4},ac=> { foreach(ac中的变量guid) { Console.WriteLine(guid+“:”+DateTime.Now.ToString(“MM/dd/yyyy hh:MM:ss.fff”); var dbMembersToProcess=tmpdtListofTransaction.AsEnumerable()。其中(p=>object.Equals(p[“ProcessSet\u GUID”],GUID)&&p[“outbound\u xml”!=null); foreach(dbMembersToProcess中的var成员) { PushWWRequest.SendTransactions(成员[“outbound_xml”].ToString(),成员[“type_of_transaction”].ToString(),成员[“MembershipEnrollmentStatus_ID_PKID”].ToString(),Convert.ToInt32(成员[“Error_Counter”].ToString()); } } }); } } } sqlConn.Close(); } } 公共静态void SendTransactions(string sRequest,string sTransactionType,string sPKID=“”,int ErrorCounter=0) { 开关(绞线式) { 案例TransactionType.INITIALENROLLMENT: 尝试 { CMInitialCustomerSetupTypeClient svcInitialCustomerSetupClientProxy=ClientOrbProxy(); CMInitialCustomerSetupInitialCustomerSetupRequest=反序列化(sRequest); svcInitialCustomerSetupClientProxy.CMInitialCustomerSetup(initialCustomerSetupRequest); } 捕获(System.ServiceModel.CommunicationException svcexpt) { 打印SVCExpt } 打破 } },c#,multithreading,C#,Multithreading,我试图一次使用4个线程发送4个请求(定义为上面的并行度设置为4),以便在Parallel.ForEach循环中使用上述代码进行处理,但我没有看到同时执行4个请求,线程以随机顺序处理。我不确定我在这里做错了什么 任何建议都会很有帮助…谢谢 既然你的问题相当琐碎,我就用其他一些建议来回答 您不应该使用Parallel。ForEach与IO绑定的任务一起使用会浪费线程和资源,asyncwait模式是一种更好的方法,它会在等待IO完成端口时将线程释放回操作系统,我会考虑一个 ActhBug 两个世界中

我试图一次使用4个线程发送4个请求(定义为上面的并行度设置为4),以便在
Parallel.ForEach
循环中使用上述代码进行处理,但我没有看到同时执行4个请求,线程以随机顺序处理。我不确定我在这里做错了什么


任何建议都会很有帮助…谢谢

既然你的问题相当琐碎,我就用其他一些建议来回答

  • 您不应该使用
    Parallel。ForEach
    与IO绑定的任务一起使用会浪费线程和资源,
    async
    wait
    模式是一种更好的方法,它会在等待IO完成端口时将线程释放回操作系统,我会考虑一个<代码> ActhBug 两个世界中最好的。

  • 你的代码乱七八糟(用最好的方式说)

  • MaxDegreeOfParallelism
    只是一个建议,而不是一个合同,TPL将决定它需要什么并认为合适

  • 如果以并行方式运行,就不能保证什么将以什么顺序执行,这就是并行编程的思想,线程有一定的自由度,并且不能保证顺序

  • 您正在到处创建引用副本,不需要这样做,即
    var tmpdtListofTransaction=dtlistofttransaction

  • DataTable dtListofTransaction=new DataTable()
    应位于using语句中

  • 减少嵌套以提高可读性,仅仅因为您可以将内容放入lambda语句并不意味着您应该简化嵌套

  • 停止在嵌套语句中使用
    ConfigurationManager
    ,这会导致无法读取;使用表达式体属性,或将它们存储在变量中一次,然后使用它完成


如果您想一次确保4个线程,请考虑将它们作为任务,并使用<代码> WaitAll < /C> >或<代码>,当所有根据您想要的,可能是“代码>等待任务”。代码>

由于您的问题相当琐碎,我将用其他一些建议来回答您的问题

  • 你不应该使用
    Parallel。ForEach
    与IO绑定的任务,你在浪费线程和资源,
    async
    wait
    模式是一种更好的方法,它将在
    public void GetTopRequest()
    {
            DataTable dtListofTransaction = new DataTable();
            string sconnection = ConfigurationManager.AppSettings[ConfigurationManager.AppSettings["BUToProcess"].ToString()].ToString();
            string query = "select Error_Counter, MembershipEnrollmentStatus_ID_PKID, outbound_xml, type_of_transaction, ProcessSet_GUID from MES where TP = 0 and RS = 'A' and type_of_transaction = 'Initial Enrollment'";
    
            using (SqlConnection sqlConn = new SqlConnection(sconnection))
            {
                sqlConn.Open();
    
                using (SqlCommand cmd = new SqlCommand(query, sqlConn))
                {
                    dtListofTransaction.Load(cmd.ExecuteReader());
                    var tmpdtListofTransaction = dtListofTransaction;
    
                    if (dtListofTransaction.Rows.Count > 0)
                    {
                        var distinctListOfFamilies = (from row in tmpdtListofTransaction.AsEnumerable()
                                                      select row.Field<Guid>("ProcessSet_GUID")).Distinct().ToList();
                        int countOfFamilies = distinctListOfFamilies.Count();
                        int FamiliesToBeProcessedByThread = (countOfFamilies > 50 ? (countOfFamilies / Convert.ToInt32(ConfigurationManager.AppSettings["ThreadsToUse"])) + 1 : countOfFamilies);
                        var listOfSubscriberLists = splitList<Guid>(distinctListOfFamilies, FamiliesToBeProcessedByThread);
                        var tmplistOfSubscriberLists = listOfSubscriberLists;
    
                        if (countOfFamilies > 0)
                        {
                            Parallel.ForEach(listOfSubscriberLists,, new ParallelOptions { MaxDegreeOfParallelism = 4}, ac => 
                            {
                                foreach (var guid in ac)
                                {
                                    Console.WriteLine(guid + " : " + DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff"));
                                    var dbMembersToProcess = tmpdtListofTransaction.AsEnumerable().Where(p => object.Equals(p["ProcessSet_GUID"], guid) && p["outbound_xml"] != null);
    
                                    foreach (var member in dbMembersToProcess)
                                    {
                                        PushWWRequest.SendTransactions(member["outbound_xml"].ToString(), member["type_of_transaction"].ToString(), member["MembershipEnrollmentStatus_ID_PKID"].ToString(), Convert.ToInt32(member["Error_Counter"].ToString()));
                                    }
                                }
                            });
                        }
                    }
                }
    
                sqlConn.Close();
            }
        }
    
        public static void SendTransactions(string sRequest, string sTransactionType, string sPKID = "", int ErrorCounter = 0)
        {
            switch (sTransactionType)
            {
                case TransactionType.INITIALENROLLMENT:
                    try
                    {
                        CMInitialCustomerSetupTypeClient svcInitialCustomerSetupClientProxy = ClientOrmbProxy<CMInitialCustomerSetupTypeClient>();
                        CMInitialCustomerSetup initialCustomerSetupRequest = Deserialize<CMInitialCustomerSetup>(sRequest);                   
                        svcInitialCustomerSetupClientProxy.CMInitialCustomerSetup(initialCustomerSetupRequest);
                    }
                    catch (System.ServiceModel.CommunicationException svcExcpt)
                    {
                        print svcExcpt
                    }
                    break;
         }
     }