在过去的两周里,我一直在解决这个问题,现在我已经束手无策了。我已经尽可能地缩小了范围,并且我真的发布了这个,希望有人可以证实我的分析并可能提出行动方案。
我将介绍应用程序中到目前为止发生的事情,以便我们都在同一页面上。编写该应用程序是为了查询数据库并检索包含用户信息和用户电子邮件地址的三个随机记录,然后对于返回的每条记录,我们检查类型是什么并根据类型发送电子邮件。我已经在本地测试过这个过程,它每次执行都没有问题,但是一旦它被编译成可执行文件并放在服务器上每隔 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……是的…… .
每次发送电子邮件时写入的日志文件仅显示第一封电子邮件已发送,而从未记录第二封……更奇怪的是。在这一点上,我唯一能想到的事情是,不知何故,该进程最初从服务器执行了两次,然后在初始进程仍在运行时再次执行,并且它们以某种方式发生冲突???我不知所措……如果有人能对可能发生的事情有所了解,那或多或少会让我的一个月!:/