1

在过去的两周里,我一直在解决这个问题,现在我已经束手无策了。我已经尽可能地缩小了范围,并且我真的发布了这个,希望有人可以证实我的分析并可能提出行动方案。

我将介绍应用程序中到目前为止发生的事情,以便我们都在同一页面上。编写该应用程序是为了查询数据库并检索包含用户信息和用户电子邮件地址的三个随机记录,然后对于返回的每条记录,我们检查类型是什么并根据类型发送电子邮件。我已经在本地测试过这个过程,它每次执行都没有问题,但是一旦它被编译成可执行文件并放在服务器上每隔 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……是的…… .

每次发送电子邮件时写入的日志文件仅显示第一封电子邮件已发送,而从未记录第二封……更奇怪的是。在这一点上,我唯一能想到的事情是,不知何故,该进程最初从服务器执行了两次,然后在初始进程仍在运行时再次执行,并且它们以某种方式发生冲突???我不知所措……如果有人能对可能发生的事情有所了解,那或多或少会让我的一个月!:/

4

1 回答 1

0

在追踪到哪些服务器正在发送电子邮件后,我们终于找到了这个问题。发生的事情是有一个旧版本的 .exe 设置运行,每个人都忘记了,这两者相互冲突。由于它们被设置为在发送后将行标记为已发送,因此旧的 .exe 会不时提取一条记录并在新的 .exe 运行后立即发送它,但在它有机会将其标记为已发送之前,从而产生随机记录的重复。

于 2013-11-07T15:45:53.513 回答