并行 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);
}
应该可以解决您的问题。
我正在尝试向数千人发送一封电子邮件,并在并行的 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);
}
应该可以解决您的问题。