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()); } } } }
关键修改点说明
- 复用
SmtpClient:把SmtpClient的创建移到循环外部,一个客户端可以发送多封邮件,减少连接建立的开销,也避免触发服务器的连接限制。 - 自动释放资源:用
using语句包裹SmtpClient和MailMessage,它们都实现了IDisposable接口,using会在代码块结束后自动调用Dispose(),释放网络连接和内存资源。 - 添加异常捕获:捕获每一次发送的异常,能明确看到哪一封邮件失败、失败原因是什么(比如无效邮箱、服务器拒绝、认证错误等),方便精准排查。
- 清理冗余代码:原代码中定义的
StringBuilder sb没有实际使用,直接用Message变量作为邮件内容即可(如果你的Message是已经拼接好的HTML内容)。
额外排查建议
- 检查你的邮件服务器是否有发送频率限制,比如短时间内发送过多邮件会被临时拦截,可以尝试在循环中添加短暂延迟(
Thread.Sleep(1000))测试。 - 确认
dsAllocateUser中的所有EMailID都是有效的邮箱格式,无效地址可能导致发送失败。 - 验证SMTP账号的密码是否正确,以及账号是否有批量发送邮件的权限。
- 如果服务器要求SSL连接,记得开启
smtpMesg.EnableSsl = true,同时确认端口是否对应(比如SSL常用465端口)。
内容的提问来源于stack exchange,提问作者Amol Naik
相关产品推荐
相关产品推荐

