使用 SendAsync 时如何在 VB 中处理 System.Net.Mail.MailMessage

How do I dispose System.Net.Mail.MailMessage in VB when using SendAsync

我没有设法在此处或 MSDN 中找到关于此问题的最终答案。使用以下代码时,如果我在发送异步邮件后尝试处理邮件,则会收到 System.ObjectDisposedException: 无法访问已处理的对象。 这是 Microsoft 示例建议处置。 我无法在回调中处理消息,因为它超出了范围。我曾尝试使用模块级邮件消息,但得到了相同的结果。如果我不处理消息,一切正常,但这不是好的做法。请告知处理邮件消息的最佳位置。

 Public Sub SendEmailWithReport(ByVal v_objEmailAddress As System.Collections.Generic.List(Of String), ByVal v_strSubject As String,
   ByVal v_strBody As String, ByVal v_strFileName As String, ByVal v_intContentID As Integer,
   ByVal v_strType As String) Implements IMessagingPlatform.SendEmailWithReport

    Dim objMessage As New MailMessage
    Dim objAttachment As New Attachment(v_strFileName, MediaTypeNames.Application.Pdf)

    Try
        'configure e-mail addresses and add attachment
        With objMessage
            For Each strAddress As String In v_objEmailAddress
                .To.Add(strAddress)
            Next
            .Attachments.Add(objAttachment)
        End With

        SetUpAsynchEmail(objMessage, v_strSubject, v_strBody, v_strFileName, v_intContentID, v_strType)

    Catch ex As Exception
        Trace.WriteLine(DateTime.Now().ToString("dd/MM/yyyy HH:mm:ss.fff") & " : Failed to setup e-mail with report: " & ex.Message.ToString, "ERR")
    Finally
        'objMessage.Dispose() *disposing here gives System.ObjectDisposedException: Cannot access a disposed object.**
        'objAttachment.Dispose()
    End Try
End Sub

Private Sub SetUpAsynchEmail(ByVal v_objMessage As MailMessage, ByVal    v_strSubject As String, ByVal v_strBody As String,
                              ByVal v_strFileName As String, ByVal v_intContentID As Integer, ByVal v_strType As String)
    Dim intID As Integer
    Try
        Dim basicAuthenticationInfo As New System.Net.NetworkCredential(mstrUserName, mstrPassword)
        Dim objClient As New SmtpClient()

        'configure mail message
        With v_objMessage
            .IsBodyHtml = True
            .Subject = v_strSubject
            .Body = v_strBody

            If mstrFromEmailName <> "" Then
                .From = New MailAddress(mstrFromEmailAddress, mstrFromEmailName)
            Else
                .From = New MailAddress(mstrFromEmailAddress)
            End If
        End With

        'configure mail client
        With objClient
            .Host = mstrSMTPHost
            .UseDefaultCredentials = False
            .Credentials = basicAuthenticationInfo
            .EnableSsl = True
            .Port = mintSMTPPort
        End With

        ' Set the method that is called back when the send operation ends. 
        AddHandler objClient.SendCompleted, AddressOf SendCompletedCallback
        'Generate a unique message number
        intID = mobjContainer.AddUnsentMail(v_intContentID, v_strType, v_strFileName)
        If intID > -1 Then
            objClient.SendAsync(v_objMessage, intID)
        End If

        'v_objMessage.Dispose() **disposing here gives System.ObjectDisposedException: Cannot access a disposed object.

    Catch ex As Exception
        Trace.WriteLine(DateTime.Now().ToString("dd/MM/yyyy HH:mm:ss.fff") & " : Failed to setup e-mail: " & ex.Message.ToString, "ERR")
    Finally

    End Try
End Sub

Private Sub SendCompletedCallback(ByVal v_objSender As SmtpClient, ByVal e As AsyncCompletedEventArgs)
    ' Get the unique identifier for this asynchronous operation. 
    Dim strMessageID As String = CStr(e.UserState)

    Try
        If e.Cancelled Then
            Trace.WriteLine(DateTime.Now().ToString("dd/MM/yyyy HH:mm:ss.fff") & " : E-mail cancelled for message with ID " &
                            strMessageID, "ERR")
        End If
        If e.Error IsNot Nothing Then
            Trace.WriteLine(DateTime.Now().ToString("dd/MM/yyyy HH:mm:ss.fff") & " : Failed to send e-mail with ID " &
                            strMessageID & ", " & e.Error.ToString(), "ERR")
            'E-mail error - update table
            mobjContainer.UpdateUnsentMail(CInt(strMessageID))
        Else
            'E-mail success - delete record from table
            mobjContainer.DeleteUnsentMailItem(CInt(strMessageID))
            Trace.WriteLineIf(mobjLogTrace.LogEvents = True And mobjLogTrace.LogDetail >= 4, DateTime.Now().ToString("dd/MM/yyyy HH:mm:ss.fff") &
                              " : E-mail with ID " & strMessageID & " successfully sent", "EVT")
        End If

    Catch objException As Exception
        Trace.WriteLine(DateTime.Now().ToString("dd/MM/yyyy HH:mm:ss.fff") & " : Failed to send e-mail with ID " &
                           strMessageID & ", " & objException.ToString(), "ERR")
    Finally
        v_objSender.Dispose()
    End Try
End Sub

如果您创建了一个 class 来保存 intID 和您的 v_objMessage 并将其作为第二个参数传递给您的 objClient.SendAsync() 调用,您将可以访问这两个 ID和 SendCompletedCallback() 子中的消息。然后,您可以在 Finally 块中对消息调用 .Dispose。