Problem sending mails with multiple threads
i have a pro开发者_如何学Goblem 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:
foreach(string s in liste)
new Thread(x => SendMail(s)).Start();
With a Parallel.ForEach
:
Parallel.ForEach(liste, SendMail);
Or, inappropriate for the case but works the .ForAll()
extension:
liste.AsParallel().ForAll(SendMail);
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 s
from the foreach that doesn't belong to it. The thread it passing a the value of s
into SendMain, but it's getting that value when it's ready for it...and that may be after the foreach
loop has already moved on, meaning that the string that s
points to has changed.
For example: If 2 threads start, one slow and one fast...the first slow one might get an s
from a later foreach()
iteration, and the faster one may get the correct s
for the current loop. That means 2 threads got the same s
reference, and the first thread copied the wrong value to pass into SendMail()
.
精彩评论