使用SendAsync时,如何在VB中部署System.Net.Mail.MailMessage

时间:2015-01-22 10:03:56

标签: vb.net email dispose sendasync

我无法在此处或MSDN中找到确凿的答案。使用下面的代码时,如果我在发送异步邮件后尝试处理该消息,那么我得到一个 System.ObjectDisposedException:无法访问已处置的对象。这是微软示例建议处置​​的时候。 我无法在回调中处理消息,因为它超出了范围。我尝试使用模块级邮件消息,但得到相同的结果。如果我不处理该消息,一切正常,但这不是好的做法。请建议处理邮件消息的最佳位置。

 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

1 个答案:

答案 0 :(得分:0)

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