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/

相关文章:

java - Web 模块之间是否共享线程?

c# - Entity Framework 如何处理数据库表中的默认约束?

c# - 锦标赛分组算法(NCAA 等)

c# - 无法读取 ASP.NET WebApi Controller 中的 Request.Content

c# - 为什么我不能将派生泛型类型转换为基本非泛型类型(通过约束)?

c# - 使用变量中的常量动态生成 lambda 表达式

c# - 使用 MVCContrib 对 MVC 3 Controller 和 View 进行单元测试时,将键和值添加到 RouteData

Java 等效于以下静态只读 C# 代码?

multithreading - C++/CLI 线程 - InvalidProgramException

c++ - 线程创建操作是否暗示发生在关系之前?