创建手动线程 – 但获取重复的线程

问题:获取重复的项目,即创建的线程数量超过数组大小…嗨,伙计们,我在循环中为数组的每个元素创建线程。 真正的用途是使用亚马逊ses发送一批消息。 消息存储在messageamazonRequestBatch中,循环遍历批处理并发送消息。

这是代码:

Thread thrdSendEmail; try { string amazonMessageID = string.Empty; List lstThread = new List(); foreach (int n in arrMessageid) { thrdSendEmail = new Thread(() => { try { amazonMessageID = SendSimpleEmail_Part2(messageAmazonRequestBatch.ElementAt(n).req); messageAmazonRequestBatch.ElementAt(n).msg.AmazonMessageID = amazonMessageID; logManager_MessageLogwithAmazonmsgID.LogMessage(",\t" + n , true); //logManager_MessageLogwithAmazonmsgID.LogMessage(",\t" + n + ",\t" + messageAmazonRequestBatch.ElementAt(n).msg.QueueMessageId + ",\t" + amazonMessageID, true); } catch (Exception ex) { logManager_RunSummary.LogMessage(ex.Message, true); } }); thrdSendEmail.Name = n.ToString(); lstThread.Add(thrdSendEmail); thrdSendEmail.Start(); //logManager_MessageLogwithAmazonmsgID.LogMessage(",\t" + n, true); } foreach (Thread t in lstThread) { t.Join(); //logManager_MessageLogwithAmazonmsgID.LogMessage(",\t" + t.Name, true); } } catch (Exception ex) { logManager_RunSummary.LogMessage(ex.Message, true); } 

我也尝试过parallel.foreach和asynch并等待选项…他们也提供了重复项。 我知道锁将解决问题,但在我的情况下,锁会降低性能10倍……这是我的性能下降了10倍…因为将sendemail登录锁定阻止直到我得到一个返回amazonmessageid来自亚马逊……

任何有关这方面的帮助将不胜感激。 我不是新手程序员,而是线程新手……

你的lambda表达式捕获循环变量n ,所以当你的lambda执行时, n的值已经改变了; 你需要将n复制到循环内的局部变量。 (假设你使用的是C#4或更早版本; C#5解决了这个问题)。

另一个问题是所有线程都使用相同的amazonMessageID变量; 你应该在lambda表达式中声明它。

  foreach (int n in arrMessageid) { int n2 = n; thrdSendEmail = new Thread(() => { try { string amazonMessageID = SendSimpleEmail_Part2(messageAmazonRequestBatch.ElementAt(n2).req); messageAmazonRequestBatch.ElementAt(n2).msg.AmazonMessageID = amazonMessageID; logManager_MessageLogwithAmazonmsgID.LogMessage(",\t" + n2 , true); //logManager_MessageLogwithAmazonmsgID.LogMessage(",\t" + n2 + ",\t" + messageAmazonRequestBatch.ElementAt(n2).msg.QueueMessageId + ",\t" + amazonMessageID, true); } catch (Exception ex) { logManager_RunSummary.LogMessage(ex.Message, true); } }); ... 

我不喜欢你的线程共享相同的变量(我的意思是namazonMessageID ),它不是线程安全的,它可能会导致你的问题。 此外,我建议您使用Parallel.ForEach方法,它可以使您的代码更容易。 它可能看起来像这样:

 try { Parallel.ForEach(arrMessageid.Distinct(), n => { try { var amazonMessageID = SendSimpleEmail_Part2(messageAmazonRequestBatch.ElementAt(n).req); messageAmazonRequestBatch.ElementAt(n).msg.AmazonMessageID = amazonMessageID; logManager_MessageLogwithAmazonmsgID.LogMessage(",\t" + n , true); } catch (Exception ex) { logManager_RunSummary.LogMessage(ex.Message, true); } } ); } catch (Exception ex) { logManager_RunSummary.LogMessage(ex.Message, true); }