You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中For循环批量发送SMTP邮件仅首封成功问题求助

解决循环发送SMTP邮件仅第一封成功的问题

你遇到的这个问题在批量发送SMTP邮件时很常见,我帮你分析下可能的原因,再给出针对性的修复方案:

核心问题分析

你当前的代码在每次循环里都创建新的SmtpClient实例,这会导致重复建立SMTP连接——很多邮件服务器会限制短时间内的并发连接数,或者旧连接没有被正确释放,直接导致后续发送请求被拒绝。另外,MailMessage没有手动释放,也可能造成资源泄漏,影响后续发送流程。

修复后的代码

我调整了代码结构,复用SmtpClient并通过using语句自动释放资源,同时添加异常捕获来定位具体错误:

DataSet dsAllocateUser = ICA_Get_EmailDatafor_User(UserId, AssignedTo, BatchID, sConnectionString);

// 把SmtpClient初始化移到循环外,复用同一个客户端发送多封邮件
using (SmtpClient smtpMesg = new SmtpClient(ConfigurationSettings.AppSettings["SmtpServer"].ToString()))
{
    smtpMesg.UseDefaultCredentials = false;
    smtpMesg.Port = 25;
    smtpMesg.Host = "smtp.emailsrvr.com";
    smtpMesg.Credentials = new System.Net.NetworkCredential("abc.notifications@gebbs.com", "psaaword");
    // 如果服务器要求SSL连接,取消下面这行注释
    // smtpMesg.EnableSsl = true;

    for (int i = 0; i < dsAllocateUser.Tables[0].Rows.Count; i++)
    {
        // 使用using自动释放MailMessage资源,避免内存泄漏
        using (MailMessage mailToSend = new MailMessage())
        {
            try
            {
                string recipientEmail = dsAllocateUser.Tables[0].Rows[i]["EMailID"].ToString();
                mailToSend.From = new MailAddress("abc.notifications@gebbs.com", "abc.notifications@gebbs.com");
                mailToSend.To.Add(new MailAddress(recipientEmail));
                mailToSend.IsBodyHtml = true;
                mailToSend.Body = Message; // 直接使用你定义的Message变量,原代码的StringBuilder未实际用到
                mailToSend.Subject = "Action Required";

                smtpMesg.Send(mailToSend);
                Console.WriteLine($"邮件已成功发送到: {recipientEmail}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送邮件到 {dsAllocateUser.Tables[0].Rows[i]["EMailID"]} 失败: {ex.Message}");
                // 需要详细排查的话,可以打印完整异常栈
                // Console.WriteLine(ex.ToString());
            }
        }
    }
}

关键修改点说明

  1. 复用SmtpClient:把SmtpClient的创建移到循环外部,一个客户端可以发送多封邮件,减少连接建立的开销,也避免触发服务器的连接限制。
  2. 自动释放资源:用using语句包裹SmtpClient和MailMessage,它们都实现了IDisposable接口,using会在代码块结束后自动调用Dispose(),释放网络连接和内存资源。
  3. 添加异常捕获:捕获每一次发送的异常,能明确看到哪一封邮件失败、失败原因是什么(比如无效邮箱、服务器拒绝、认证错误等),方便精准排查。
  4. 清理冗余代码:原代码中定义的StringBuilder sb没有实际使用,直接用Message变量作为邮件内容即可(如果你的Message是已经拼接好的HTML内容)。

额外排查建议

  • 检查你的邮件服务器是否有发送频率限制,比如短时间内发送过多邮件会被临时拦截,可以尝试在循环中添加短暂延迟(Thread.Sleep(1000))测试。
  • 确认dsAllocateUser中的所有EMailID都是有效的邮箱格式,无效地址可能导致发送失败。
  • 验证SMTP账号的密码是否正确,以及账号是否有批量发送邮件的权限。
  • 如果服务器要求SSL连接,记得开启smtpMesg.EnableSsl = true,同时确认端口是否对应(比如SSL常用465端口)。

内容的提问来源于stack exchange,提问作者Amol Naik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:16:51