c# - 使用多线程发送邮件时出现问题

标签 c# .net multithreading smtp

我对下面的代码有疑问。发送的邮件带有字符串 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);
        }
    }

最佳答案

由于您使用的是 .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 个线程,一个慢一个快……第一个慢的线程可能会从后面的 foreach() 迭代中得到一个 s,并且速度越快的可能会得到当前循环的正确 s。这意味着 2 个线程获得了相同 s 引用,而第一个线程复制了错误的值以传递给 SendMail()

关于c# - 使用多线程发送邮件时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3325342/

相关文章:

c# - TripleDES 加密和解密给出奇怪的结果

java - 寻找一种方法来停止/杀死线程

.net - 在安装过程中初始化 user.config 或 app.exe.config

c++ - 为什么我不能在信号上启动QThread?

c++ - 删除指针有时会导致堆损坏

c# - 将表达式<Func<T,T,bool>> 转换为表达式<Func<T,bool>>

c# - 如何从 C# 中的 Object[] 中删除特定类型的变量

c# - 假人的表达树?

.NET Image.RemovePropertyItem 无明显效果

.net - 如何使用反射通过属性标签名称设置属性值?