i have a problem with the code below. the mail is sent with a duplicate content of the string s. why is this happening?
static void Main(string[] args)
{
List<String> liste = new List<String>();
liste.Add("1");
liste.Add("2");
liste.Add("3");
liste.Add("4");
liste.Add("5");
liste.Add("6");
foreach(string s in liste)
new Thread(x => SendMail(s)).Start();
}
static void SendMail(string s)
{
MailMessage mailMsg = new MailMessage("from", "to");
mailMsg.Body = s;
mailMsg.Subject = s;
SmtpClient smtpClient = new SmtpClient("mySMTP");
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = new NetworkCredential("myUse", "myPass");
smtpClient.EnableSsl = true;
try
{
smtpClient.Send(mailMsg);
}
catch (SmtpException ex)
{
Console.WriteLine(ex.Message);
}
}
Since you’re using .Net 4.0 you can use a few new constructs available here, you can replace this:
With a
Parallel.ForEach:Or, inappropriate for the case but works the
.ForAll()extension:Someone correct me here, but what I think is happening is that if a Thread takes any time to start up it’s referencing a
sfrom the foreach that doesn’t belong to it. The thread it passing a the value ofsinto SendMain, but it’s getting that value when it’s ready for it…and that may be after theforeachloop has already moved on, meaning that the string thatspoints to has changed.For example: If 2 threads start, one slow and one fast…the first slow one might get an
sfrom a laterforeach()iteration, and the faster one may get the correctsfor the current loop. That means 2 threads got the samesreference, and the first thread copied the wrong value to pass intoSendMail().