Проблема отправки почты с несколькими потоками - PullRequest
2 голосов
/ 24 июля 2010

У меня проблема с кодом ниже.письмо отправлено с дублированным содержимым строки 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);
        }
    }

1 Ответ

4 голосов
/ 24 июля 2010

Поскольку вы используете .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);

Кто-то поправляет меня здесь, но я думаю, что происходит, что если поток занимает любое время для запуска, он ссылается на s из foreach, который не принадлежать к нему. Поток передает значение s в SendMain, , но это получает это значение, когда оно к нему готово ... и это может быть после того, как цикл foreach уже перешел, что означает, что строка, на которую указывает s, изменилась.

Например: если запускаются 2 потока, один медленный и один быстрый ... первый медленный может получить s от более поздней итерации foreach(), а более быстрый может получить правильный s для токовая петля. Это означает, что 2 потока получили одинаковую ссылку s, и первый поток скопировал неправильное значение для передачи в SendMail().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...