SSIS使用脚本任务发送邮件出现超时错误如何解决
SSIS Script Task 发送Office365邮件超时问题修复方案
问题根因
- 代码未正确释放
MailMessage、SmtpClient、Attachment资源,循环执行时会占用大量SMTP连接,最终导致连接耗尽触发超时 - 存在多余未使用的Attachment实例,额外占用系统资源
- Office365 SMTP默认禁用基础密码认证,旧的明文密码认证方式会被拦截导致连接超时
- 防火墙/网络策略可能拦截SSIS运行环境到smtp.office365.com 587端口的出站请求
- 循环发送频率过高触发Office365 SMTP限流规则
修复步骤
1. 优先排查网络与账号配置
- 在SSIS运行的服务器上执行
telnet smtp.office365.com 587测试端口连通性,不通的话先放开防火墙出站规则 - 确认发件邮箱已开启SMTP AUTH权限:登录Office365管理员中心,找到对应用户,在「邮件」-「电子邮件应用」中开启「经过身份验证的SMTP」
- 如果账号开启了MFA,不能直接用登录密码,需要在账号安全设置中创建应用密码,替换代码里的密码字段
- 若完成以上配置后仍超时,可去Office365邮件管理中心查看对应账号的投递日志,确认是否被反垃圾规则拦截
2. 优化C#代码,修复资源泄漏问题
所有实现了IDisposable接口的对象都使用using块包裹,执行完自动释放资源,同时删除多余无效代码,增加附件存在性校验避免异常。
3. 循环逻辑优化
如果是批量循环发送邮件,每发送1封后增加3-5秒的等待时间,避免触发Office365的SMTP发送频率限制(大附件场景下限流规则更严格)。
修复后完整代码
#region Namespaces using System; using System.Data; using Microsoft.SqlServer.Dts.Runtime; using System.Windows.Forms; using System.Text; using System.Net; using System.Net.Mail; using System.IO; using System.Threading; using Microsoft.SqlServer.Dts; #endregion namespace ST_01aa093042ba46959a419d75a80d117c { [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute] public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase { public void Main() { try { string fromString = (string)Dts.Variables["User::Email_From"].Value; string toString = (string)Dts.Variables["User::Email_TO"].Value; string ccString = (string)Dts.Variables["User::Email_CC"].Value; string attachmentName = (string)Dts.Variables["User::Pdf_Send_Path"].Value; string attachmentName1 = (string)Dts.Variables["User::Excel_Send_Path"].Value; string emailBody = (string)Dts.Variables["User::Email_Body"].Value; string emailSubject = (string)Dts.Variables["User::Email_Subject"].Value; // using块自动释放资源 using (MailMessage mail = new MailMessage()) using (SmtpClient SmtpServer = new SmtpClient("smtp.office365.com", 587)) { mail.From = new MailAddress(fromString); mail.To.Add(toString); if (!string.IsNullOrEmpty(ccString)) { mail.CC.Add(ccString); } mail.Subject = emailSubject; mail.IsBodyHtml = false; mail.Body = emailBody; // 校验附件存在再添加,避免空附件异常 if (File.Exists(attachmentName)) { mail.Attachments.Add(new Attachment(attachmentName)); } if (File.Exists(attachmentName1)) { mail.Attachments.Add(new Attachment(attachmentName1)); } SmtpServer.EnableSsl = true; SmtpServer.UseDefaultCredentials = false; // 开启MFA的话这里替换为你生成的应用密码 SmtpServer.Credentials = new NetworkCredential("user@domain.com.tr", "你的有效认证密码"); // 大附件场景可将超时调整为300秒 SmtpServer.Timeout = 300000; SmtpServer.Send(mail); } // 循环发送场景下增加等待时间,避免触发限流 Thread.Sleep(3000); Dts.TaskResult = (int)ScriptResults.Success; } catch (Exception ex) { MessageBox.Show(ex.ToString()); Dts.Variables["User::Error_Value"].Value = 1; Dts.TaskResult = (int)ScriptResults.Failure; } } #region ScriptResults declaration enum ScriptResults { Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success, Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure }; #endregion } }
内容的提问来源于stack exchange,提问作者rkapukaya
相关产品推荐
相关产品推荐

