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 } 打破 } }
我试图一次使用4个线程发送4个请求(定义为上面的并行度设置为4),以便在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 两个世界中
Parallel.ForEach
循环中使用上述代码进行处理,但我没有看到同时执行4个请求,线程以随机顺序处理。我不确定我在这里做错了什么
任何建议都会很有帮助…谢谢 既然你的问题相当琐碎,我就用其他一些建议来回答
- 您不应该使用
与IO绑定的任务一起使用会浪费线程和资源,Parallel。ForEach
async
模式是一种更好的方法,它会在等待IO完成端口时将线程释放回操作系统,我会考虑一个<代码> ActhBug 两个世界中最好的。wait
- 你的代码乱七八糟(用最好的方式说)
只是一个建议,而不是一个合同,TPL将决定它需要什么并认为合适MaxDegreeOfParallelism
- 如果以并行方式运行,就不能保证什么将以什么顺序执行,这就是并行编程的思想,线程有一定的自由度,并且不能保证顺序
- 您正在到处创建引用副本,不需要这样做,即
var tmpdtListofTransaction=dtlistofttransaction代码>
应位于using语句中DataTable dtListofTransaction=new DataTable()
- 减少嵌套以提高可读性,仅仅因为您可以将内容放入lambda语句并不意味着您应该简化嵌套
- 停止在嵌套语句中使用
,这会导致无法读取;使用表达式体属性,或将它们存储在变量中一次,然后使用它完成ConfigurationManager
如果您想一次确保4个线程,请考虑将它们作为任务,并使用<代码> WaitAll < /C> >或<代码>,当所有根据您想要的,可能是“代码>等待任务”。代码>
由于您的问题相当琐碎,我将用其他一些建议来回答您的问题- 你不应该使用
与IO绑定的任务,你在浪费线程和资源,Parallel。ForEach
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; } }