过去两周我一直在解决这个问题,而且我的智慧结束了。我已经尽可能地缩小了范围,我真的发布了这个,希望有人可以确认我的分析,并可能建议采取行动。
我将逐步了解应用程序中的这一点,以便我们都在同一页面上。编写应用程序以查询数据库并检索包含用户信息和用户电子邮件地址的三个随机记录,然后对于返回的每个记录,我们检查以查看类型,并根据类型发送电子邮件。我已经在本地测试了这个过程并且每次都没有问题地执行,但是一旦将其编译成可执行文件并放置在服务器上以每15分钟的间隔执行,用户就开始抱怨收到多个同样的电子邮件记录....我将发布一些代码,然后解释我到目前为止所发现的内容:
Module Module1
Sub Main()
CreateExecutionLogFile(DateTime.Now.ToString, "BEGIN")
Dim dtEmails As DataTable = RetreiveEmailsToSend()
For Each dr As DataRow In dtEmails.Rows
With dr
Select Case .Item("EmailType").ToString.Trim
Case "NEW"
SendNewEmail(.Item("EmpUserID").ToString.Trim, .Item("EmpEmailAddress").ToString.Trim, .Item("EmpFullName").ToString.Trim, _
CInt(.Item("RecordIDPK").ToString.Trim), .Item("SupervisorEmailAddress").ToString.Trim)
Case "24H"
Send24hEmail(.Item("EmpUserID").ToString.Trim, .Item("EmpEmailAddress").ToString.Trim, .Item("EmpFullName").ToString.Trim, _
CInt(.Item("RecordIDPK").ToString.Trim), .Item("SupervisorEmailAddress").ToString.Trim)
Case "48H"
Send48hEmail(.Item("EmpUserID").ToString.Trim, .Item("EmpEmailAddress").ToString.Trim, .Item("EmpFullName").ToString.Trim, _
CInt(.Item("RecordIDPK").ToString.Trim), .Item("SupervisorEmailAddress").ToString.Trim)
End Select
UpdateRecordAfterEmail(CInt(.Item("RecordIDPK").ToString.Trim), .Item("EmailType").ToString.Trim)
End With
Next
CreateExecutionLogFile(DateTime.Now.ToString, "END")
End Sub
''Send24hEmail() and Send48hEmail() are mirrors of this function with only the wording in the email body being changed
''therefore I only include the following function to make things easier to read in this post
Private Sub SendNewEmail(ByVal EmpUserID As String, ByVal EmpEmailAddress As String, ByVal EmpFullName As String, ByVal RecordID As Integer, ByVal SupEmailAddress As String)
Dim strFrom As String = "DoNotReply@test.place"
Dim strTo As String = EmpEmailAddress
Dim strSubject As String = "TEST SUBJECT"
Dim strCC As String = SupEmailAddress.Trim
Dim strMessage As New StringBuilder
With strMessage
.Append("Hello!//EMAIL BODY IS BUILT HERE")
.Append(DateTime.Now.ToString())
End With
SendEmail(strFrom, strTo, strSubject, strMessage.ToString, strCC, RecordID.ToString, "NEW", EmpUserID)
End Sub
Private Sub UpdateRecordAfterEmail(ByVal RecordID As Integer, ByVal EmailType As String)
'Connects to database and runs query to update the record as sent
End Sub
Public Sub SendEmail(ByVal strFrom As String, ByVal strTo As String, ByVal strSubject As String, ByVal strMessage As String, ByVal strCC As String, ByVal recordID As String, ByVal type As String, ByVal userID As String)
If CheckIfEmailSent(recordID, type) = False Then
If strTo > "" Then
Try
Dim MailMsg As New MailMessage()
strTo = strTo.Trim(CChar(","))
MailMsg.To.Add(strTo)
If strCC.Trim <> "" Then
MailMsg.CC.Add(strCC)
End If
MailMsg.From = New MailAddress(strFrom, "FROM MESSAGE")
MailMsg.BodyEncoding = Encoding.Default
MailMsg.Subject = strSubject.Trim()
MailMsg.Body = strMessage.Trim() & vbCrLf
MailMsg.Priority = MailPriority.High
MailMsg.IsBodyHtml = False
Dim mailClient As New SmtpClient("mail.name.place")
mailClient.UseDefaultCredentials = True
mailClient.Send(MailMsg)
MailMsg.Dispose()
CreateLogFile(recordID, type, userID, strTo)
Catch innerException As Exception
Dim MailMsg As New MailMessage()
MailMsg.To.Add("nullReference@name.place")
MailMsg.From = New MailAddress(strFrom, "FROM MESSAGE - ERROR")
MailMsg.BodyEncoding = Encoding.Default
MailMsg.Subject = strSubject.Trim()
MailMsg.Body = strMessage.Trim() & vbCrLf & vbCrLf & vbCrLf & innerException.Message
MailMsg.Priority = MailPriority.High
MailMsg.IsBodyHtml = False
Dim mailClient As New SmtpClient("mail.name.place")
mailClient.UseDefaultCredentials = True
mailClient.Send(MailMsg)
MailMsg.Dispose()
End Try
End If
Else
CreateLogFile("*ERROR* ATTEMPTED RESEND" + " " + recordID, type, userID, strTo)
End If
End Sub
Private Function CheckIfEmailSent(recordID As Integer, type As String) As Boolean
''Connect to database determine if recordID has already been sent
''If it has return true, else return false
End Function
Private Sub CreateLogFile(ByVal recordID, ByVal type, ByVal userID, ByVal email)
''Create log file on server containing information passed to function and
''current datetime
End Sub
Private Sub CreateExecutionLogFile(time As String, beginEnd As String)
''Create log file on server containing the time passed and either "BEGIN"
''or "END" depending on the value in "beginEnd"
End Sub
End Module
我最初在SendEmail()例程(CheckIfEmailSent())中放置了一个补丁,该例程连接到数据库,并在发送另一封电子邮件之前检查该记录是否已被标记为已发送。我认为这会很快解决问题,但我很快就被证明是错误的。
现在,由于问题在上述修补程序之后仍然存在,我开始认为它与smtp邮件客户端挂起并发送多封电子邮件有关,但后来我意识到情况并非如此,因为电子邮件中包含的内容是不同的,这意味着SendNewEmail()函数必须运行两次以生成新的时间值,以便在将电子邮件发送到SendEmail()函数之前放置在电子邮件的正文字符串中...... .0_0 ... 。是啊...
每次发送电子邮件时写入的日志文件都会显示第一封电子邮件已发送,而且从未记录第二封电子邮件......更奇怪。 在这一点上,我能想到的唯一事情是,不知何故,该过程最初从服务器执行两次,然后在初始进程仍在运行时再次执行两次并且它们是冲突的???我很茫然...如果有人能够对可能发生的事情有所了解,那么我或多或少就会成功! :/
答案 0 :(得分:0)
在追踪哪些服务器正在发送电子邮件之后,我们终于找到了这个问题。发生的事情是,有一个旧版本的.exe设置运行,每个人都忘记了,这两个是相互冲突的。因为它们被设置为在发送之后将行标记为已发送,所以旧的.exe将不时地拉出记录并在新的运行之后立即发送它但是它有机会将其标记为已经发送,从而产生重复随机记录。