Vb.net 内部exchange smtp服务器上包含system.net.mail的大量邮件超时
我正在制定一个计划,每周向我们公司的每位销售员工发送提醒/更新。每周大约120个,自动化,在短时间内完成。这是一个内部程序,仅面向内部收件人,我不担心垃圾邮件或不想要的消息,取消订阅也不是一个选项。每封邮件都根据每位销售人员的客户列表进行个性化处理,并包含每周“待办事项”,供他们致电客户 我在内部运行呼气2007,为我的开发环境和运行这些自动化项目的服务器提供了一个开放的内部SMTP连接器。该程序在一两家商店中运行良好,但当我为每家商店运行它时,在发送110条消息后,我会在某处超时 我并没有尝试将邮件排队或将它们分块存放,当我遍历销售人员列表,并执行每个相应的查找和邮件生成时,我正在尝试使用以下子项发送邮件Vb.net 内部exchange smtp服务器上包含system.net.mail的大量邮件超时,vb.net,system.net.mail,Vb.net,System.net.mail,我正在制定一个计划,每周向我们公司的每位销售员工发送提醒/更新。每周大约120个,自动化,在短时间内完成。这是一个内部程序,仅面向内部收件人,我不担心垃圾邮件或不想要的消息,取消订阅也不是一个选项。每封邮件都根据每位销售人员的客户列表进行个性化处理,并包含每周“待办事项”,供他们致电客户 我在内部运行呼气2007,为我的开发环境和运行这些自动化项目的服务器提供了一个开放的内部SMTP连接器。该程序在一两家商店中运行良好,但当我为每家商店运行它时,在发送110条消息后,我会在某处超时 我并没有尝试
Sub doMail(ByRef MessageBody As String, ByVal nameString As String, ByVal sendTo As ArrayList, Optional ByVal markurgent As Boolean = False, _
Optional ByVal sendCC As ArrayList = Nothing, Optional ByVal sendBcc As ArrayList = Nothing)
Try
' Setup Mail Message
Dim oClient As SmtpClient = New SmtpClient(ConfigurationManager.AppSettings("mail_server").ToString())
oClient.Timeout = 20000
'oClient.Port = 50747
Dim objMessage As New MailMessage()
objMessage.From = New System.Net.Mail.MailAddress(ConfigurationManager.AppSettings("mail_from_address").ToString, ConfigurationManager.AppSettings("mail_from_name").ToString)
objMessage.Subject = String.Format("Weekly Hitlist Report ~ {0}", nameString)
If (ConfigurationManager.AppSettings("debugMode").ToString() = 1) Then
Dim debugSB As StringBuilder = New StringBuilder
For Each s As String In sendTo
debugSB.AppendLine(String.Format("To: {0}<br>", s))
Next
For Each s As String In sendCC
debugSB.AppendLine(String.Format("cc: {0}<br>", s))
Next
For Each s As String In sendBcc
debugSB.AppendLine(String.Format("bcc: {0}<br>", s))
Next
MessageBody = String.Format("Debug Mode is Active. <br> {0} <br><hr noshade>{1}", debugSB.ToString, MessageBody)
objMessage.To.Add(ConfigurationManager.AppSettings("mail_to_address").ToString)
Else
For Each receiver As String In sendTo
Try
objMessage.To.Add(receiver.Trim())
Catch ex As Exception
' do nothing
End Try
Next
For Each receiver As String In sendCC.ToArray
Try
objMessage.CC.Add(receiver.Trim())
Catch ex As Exception
' do nothing
End Try
Next
For Each receiver As String In sendBcc
Try
objMessage.Bcc.Add(receiver.Trim())
Catch ex As Exception
' do nothing
End Try
Next
End If
objMessage.Body = MessageBody
objMessage.Priority = IIf(markurgent, MailPriority.High, MailPriority.Normal)
objMessage.IsBodyHtml = True
oClient.Send(objMessage)
oClient = Nothing
Console.WriteLine(String.Format("{1} - message sent - {0} ", nameString, Now()))
Catch ex As Exception
Console.WriteLine(ex.Message)
Console.WriteLine("****************")
Console.WriteLine(ex.StackTrace)
End Try
End Sub
我还尝试发送每个单独的商店和较小的子集。我只在一次为整个公司运行时收到此错误
我没有看到任何禁止此操作的交换,也没有看到高消息队列在等待。有没有关于发送消息的其他方法或其他尝试的建议?(我不希望使用第三方dll或外部组件)。我经历了这个问题的痛苦。经过2年的研究,我还没能找出我的.net应用程序出现问题的确切原因。有许多问题和实施选项将有助于将此异常的影响降至最低。我们现在已经到了这样一个地步:这个问题不会以明显的方式影响最终用户
''' <summary>
''' Provide a mechanism to throttle the subsequent attempts to send emails.
''' </summary>
''' <param name="emailAddress"></param>
''' <param name="attemptNumber"></param>
''' <remarks>Need to implement a more dynamic function as attempts persist, pause for longer for a number of attempt, then add the email to a failed queue.</remarks>
Private Shared Sub RestBeforeSendingAgain(ByVal emailAddress As String, ByVal attemptNumber As Integer)
If attemptNumber > 1 Then
' Wait 30 seconds in between every attempt, or the value configured in the config file.
Dim retryIntervalInSeconds As Integer = 30
If Not String.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings.Item("SMTPFailureReTryIntervalInSeconds")) Then
Integer.TryParse(System.Configuration.ConfigurationManager.AppSettings.Item("SMTPFailureReTryIntervalInSeconds"), retryIntervalInSeconds)
End If
logger.Warn("Problem emailing {0}. Waiting {1} seconds to help clear technical issues.", emailAddress, retryIntervalInSeconds.ToString)
System.Threading.Thread.Sleep(System.TimeSpan.FromSeconds(retryIntervalInSeconds))
End If
End Sub
''' <summary>
''' Attempt to send an email message and record any issues with that mailmessage to the application log.
''' Allows the process to know the success or failure of that approach.
''' </summary>
''' <param name="mailClient"></param>
''' <param name="mailMessage"></param>
''' <param name="attemptNumber"></param>
''' <returns>The success or failure of the SMTP server to send the message without causing an error.</returns>
''' <remarks></remarks>
Private Shared Function AttemptToSendEmail(ByRef mailClient As System.Net.Mail.SmtpClient, ByRef mailMessage As MailMessage, ByVal attemptNumber As Integer) As Boolean
Dim result As Boolean = False
Try
logger.Trace("Started: AttemptToSendEmail", attemptNumber)
RestBeforeSendingAgain(mailMessage.To.ToString, attemptNumber)
mailClient.Send(mailMessage)
result = True
Catch smtpEx As SmtpException
result = False
logger.ErrorException(String.Format("{3}{1}{0}{1}{2}", ExceptionFormater.FormatException(smtpEx), Environment.NewLine, ExceptionFormater.FormatStack(smtpEx), "AttemptToSendEmail failed with Smtp exception."), smtpEx)
Catch ex As Exception
result = False
logger.ErrorException(String.Format("{3}{1}{0}{1}{2}", ExceptionFormater.FormatException(ex), Environment.NewLine, ExceptionFormater.FormatStack(ex), "AttemptToSendEmail failed with generic exception."), ex)
Finally
If result Then
logger.Trace("Succeeded: To email {0} on attempt {1}.", mailMessage.To.ToString, attemptNumber)
Else
logger.Warn("Failed: To email {0} on attempt {1}.", mailMessage.To.ToString, attemptNumber)
End If
End Try
Return result
End Function
' Configure the timeout in milliseconds from the App.Config file.
' 200 seconds = 200,000 miliseconds
MySmtpClient.Timeout = CInt(TimeSpan.FromSeconds(SmtpClientTimeoutSeconds).TotalMilliseconds)
“”
''提供一种机制来阻止后续发送电子邮件的尝试。
'''
'''
'''
''需要在尝试持续时实现更具动态性的功能,暂停更长时间以进行多次尝试,然后将电子邮件添加到失败队列。
发送增益之前的私有共享子REST(ByVal emailAddress为字符串,ByVal attemptNumber为整数)
如果尝试次数>1,则
'在每次尝试或配置文件中配置的值之间等待30秒。
Dim retryIntervalInSeconds为整数=30
如果不是String.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings.Item(“SMTPFailureReTryIntervalInSeconds”)),则
Integer.TryParse(System.Configuration.ConfigurationManager.AppSettings.Item(“SMTPFailureReTryIntervalInSeconds”),retryIntervalInSeconds)
如果结束
logger.Warn(“发送问题电子邮件{0}。等待{1}秒以帮助清除技术问题。”,emailAddress,retryIntervalInSeconds.ToString)
System.Threading.Thread.Sleep(System.TimeSpan.FromSeconds(retryIntervalInSeconds))
如果结束
端接头
'''
''尝试发送电子邮件,并将该邮件的任何问题记录到应用程序日志中。
''允许流程了解该方法的成功或失败。
'''
'''
'''
'''
''SMTP服务器发送邮件而不导致错误的成功或失败。
'''
私有共享函数attemptosendemail(ByRef mailClient作为System.Net.Mail.SmtpClient,ByRef mailMessage作为mailMessage,ByVal attemptNumber作为整数)作为布尔值
将结果设置为布尔值=False
尝试
Trace(“启动:attemptosendemail”,attemptNumber)
RestBeforeSendingAgain(mailMessage.To.ToString,attemptNumber)
mailClient.Send(mailMessage)
结果=真
将smtpEx捕获为SmtpException
结果=错误
logger.ErrorException(String.Format(“{3}{1}{0}{1}{2}”)、ExceptionFormatter.FormatException(smtpEx)、Environment.NewLine、ExceptionFormatter.FormatStack(smtpEx)、“AttemptoSendmail因Smtp异常而失败”)、smtpEx)
特例
结果=错误
logger.ErrorException(String.Format(“{3}{1}{0}{1}{2}”),ExceptionFormatter.FormatException(ex),Environment.New
''' <summary>
''' Provide a mechanism to throttle the subsequent attempts to send emails.
''' </summary>
''' <param name="emailAddress"></param>
''' <param name="attemptNumber"></param>
''' <remarks>Need to implement a more dynamic function as attempts persist, pause for longer for a number of attempt, then add the email to a failed queue.</remarks>
Private Shared Sub RestBeforeSendingAgain(ByVal emailAddress As String, ByVal attemptNumber As Integer)
If attemptNumber > 1 Then
' Wait 30 seconds in between every attempt, or the value configured in the config file.
Dim retryIntervalInSeconds As Integer = 30
If Not String.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings.Item("SMTPFailureReTryIntervalInSeconds")) Then
Integer.TryParse(System.Configuration.ConfigurationManager.AppSettings.Item("SMTPFailureReTryIntervalInSeconds"), retryIntervalInSeconds)
End If
logger.Warn("Problem emailing {0}. Waiting {1} seconds to help clear technical issues.", emailAddress, retryIntervalInSeconds.ToString)
System.Threading.Thread.Sleep(System.TimeSpan.FromSeconds(retryIntervalInSeconds))
End If
End Sub
''' <summary>
''' Attempt to send an email message and record any issues with that mailmessage to the application log.
''' Allows the process to know the success or failure of that approach.
''' </summary>
''' <param name="mailClient"></param>
''' <param name="mailMessage"></param>
''' <param name="attemptNumber"></param>
''' <returns>The success or failure of the SMTP server to send the message without causing an error.</returns>
''' <remarks></remarks>
Private Shared Function AttemptToSendEmail(ByRef mailClient As System.Net.Mail.SmtpClient, ByRef mailMessage As MailMessage, ByVal attemptNumber As Integer) As Boolean
Dim result As Boolean = False
Try
logger.Trace("Started: AttemptToSendEmail", attemptNumber)
RestBeforeSendingAgain(mailMessage.To.ToString, attemptNumber)
mailClient.Send(mailMessage)
result = True
Catch smtpEx As SmtpException
result = False
logger.ErrorException(String.Format("{3}{1}{0}{1}{2}", ExceptionFormater.FormatException(smtpEx), Environment.NewLine, ExceptionFormater.FormatStack(smtpEx), "AttemptToSendEmail failed with Smtp exception."), smtpEx)
Catch ex As Exception
result = False
logger.ErrorException(String.Format("{3}{1}{0}{1}{2}", ExceptionFormater.FormatException(ex), Environment.NewLine, ExceptionFormater.FormatStack(ex), "AttemptToSendEmail failed with generic exception."), ex)
Finally
If result Then
logger.Trace("Succeeded: To email {0} on attempt {1}.", mailMessage.To.ToString, attemptNumber)
Else
logger.Warn("Failed: To email {0} on attempt {1}.", mailMessage.To.ToString, attemptNumber)
End If
End Try
Return result
End Function
' Configure the timeout in milliseconds from the App.Config file.
' 200 seconds = 200,000 miliseconds
MySmtpClient.Timeout = CInt(TimeSpan.FromSeconds(SmtpClientTimeoutSeconds).TotalMilliseconds)