并行 Foreach 循环的奇怪行为

Parallel Foreach Loop Odd Behavior

我正在尝试向数千人发送一封电子邮件,并在并行的 foreach 循环中将其记录到数据库中,但是一些客户收到了一封具有不同客户姓名的电子邮件。我怎样才能使它线程安全?这是我的代码:

EmailEntities db = new EmailEntities();
string templateData ="";
MailHelper mh = new MailHelper();
List<Customers> allCustomers = db.Customers.ToList<Customers>();

Parallel.ForEach(allCustomers, customer =>
{
    string[] emails = customer.EmailAddress.Split(';');

    foreach (var mailItem in emails)
   {

        string email = mailItem.Trim();
        templateData = mailEntitiyData.HtmlContent;             
        templateData = templateData.Replace("##FULL_NAME##", customer.Name + " " + customer.Surname);
        var postRes = mh.SendMail(subject, templateData , email, postType, null, null, bytes);
        Logger.Log(customer.ID, email, postRes.PostID);
   }

});


 public static class Logger
{
    public static void Log( int CustomerID, string email, string messageID)
    {
        using (EmailMarketingEntities db = new EmailMarketingEntities())
        {
            MailLogs ml = new MailLogs();
            ml.CustomerID = CustomerID;              
            ml.EmailAddress = email;
            ml.MessageID = messageID;               
            db.MailLogs.Add(ml);
            db.SaveChanges();
        }
    }

}

使用这个:

foreach (var mailItem in emails)
{

    string email = mailItem.Trim();
    templateData = mailEntitiyData.HtmlContent;             
    templateData = templateData.Replace("##FULL_NAME##", customer.Name + " " + customer.Surname);
    var postRes = mh.SendMail(subject, templateData , email, postType, null, null, bytes);
    Logger.Log(customer.ID, email, postRes.PostID);
}

你实际上是在重写 mailEntitiyData.HtmlContent 内容,这绝对不是你想要做的。将其更改为:

foreach (var mailItem in emails)
{

    string email = mailItem.Trim();
    templateData = mailEntitiyData.HtmlContent;             
    var customTemplateData = templateData.Replace("##FULL_NAME##", customer.Name + " " + customer.Surname);
    var postRes = mh.SendMail(subject, customTemplateData, email, postType, null, null, bytes);
    Logger.Log(customer.ID, email, postRes.PostID);
}

应该可以解决您的问题。