2010-07-24 68 views
2

我對下面的代碼有問題。郵件與字符串s的重複內容一起發送。爲什麼發生這種情況?用多線程發送郵件時出現問題

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); 
     } 
    } 
+0

您正在使用哪個版本的.Net? – 2010-07-24 13:51:10

+0

.Net 4.0客戶端配置文件 – 2010-07-24 13:53:08

+0

您的意思是,對於每個郵件消息正文,該字符串的值會出現兩次?即身體中的「11」,「22」,「33」等? – 2010-07-24 13:55:19

回答

4

由於您使用.NET 4.0,你可以在這裏使用提供了一些新的結構,可以更換此:

foreach(string s in liste) 
    new Thread(x => SendMail(s)).Start(); 

隨着Parallel.ForEach

Parallel.ForEach(liste, SendMail); 

或者,不適合的情況下,但作品.ForAll()擴展:

liste.AsParallel().ForAll(SendMail); 

有人糾正我在這裏,但我認爲的情況是,如果一個線程需要任何時間來啓動它的引用從一個不屬於它在foreach一個s。它的線程傳遞的s一個價值爲SendMain,越來越該閾值時它已經準備好了......這可能是後foreach循環已經移動了,這意味着字符串s點已經改變。

例如:如果2個線程啓動,一個慢一快...先慢一個可以從後面foreach()迭代得到一個s,而較快的可以得到正確的s電流環。這意味着2個線程得到相同的s引用,並且第一個線程複製了錯誤的值傳入SendMail()