.NET SMTP SendAsync с AlternateViews создает выбранное исключение - PullRequest
1 голос
/ 22 апреля 2009

Я пытаюсь отправить электронную почту асинхронно, и она работает нормально, если к сообщению не прикреплен AlternateView Когда есть альтернативное представление, я получаю следующую ошибку:

Cannot access a disposed object. Object name: 'System.Net.Mail.AlternateView'
System.Net.Mail.SmtpException: Failure sending mail. ---> System.ObjectDisposedException: Cannot access a disposed object.

Object name: 'System.Net.Mail.AlternateView'.
   at System.Net.Mail.AlternateView.get_LinkedResources()
   at System.Net.Mail.MailMessage.SetContent()
   at System.Net.Mail.MailMessage.BeginSend(BaseWriter writer, Boolean sendEnvelope, AsyncCallback callback, Object state)
   at System.Net.Mail.SmtpClient.SendMailCallback(IAsyncResult result)

Вот пример кода:

Dim msg As New System.Net.Mail.MailMessage
msg.From = New System.Net.Mail.MailAddress("me@example.com", "My Name")
msg.Subject = "email subject goes here"

'add the message bodies to the mail message
Dim hAV As System.Net.Mail.AlternateView = System.Net.Mail.AlternateView.CreateAlternateViewFromString(textBody.ToString, Nothing, "text/plain")
hAV.TransferEncoding = Net.Mime.TransferEncoding.QuotedPrintable
msg.AlternateViews.Add(hAV)

Dim tAV As System.Net.Mail.AlternateView = System.Net.Mail.AlternateView.CreateAlternateViewFromString(htmlBody.ToString, Nothing, "text/html")
tAV.TransferEncoding = Net.Mime.TransferEncoding.QuotedPrintable
msg.AlternateViews.Add(tAV)

Dim userState As Object = msg
Dim smtp As New System.Net.Mail.SmtpClient("emailServer")

'wire up the event for when the Async send is completed
 AddHandler smtp.SendCompleted, AddressOf SmtpClient_OnCompleted

 Try
     smtp.SendAsync(msg, userState)
 Catch '.... perform exception handling, etc...
 End Try

И Обратный звонок .....

 Public Sub SmtpClient_OnCompleted(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
    If e.Cancelled Then
      'Log the cancelled error
    End If
    If Not IsNothing(e.Error) Then
        'Log a real error....
        ' this is where the error is getting picked up
    End If

    'dispose the message
    Dim msg As System.Net.Mail.MailMessage = DirectCast(e.UserState, System.Net.Mail.MailMessage)
    msg.Dispose()

End Sub

Ответы [ 3 ]

2 голосов
/ 24 апреля 2009

Причина, по которой это не работает, заключается в том, что ваш обработчик OnCompleted вызывается после завершения метода SendAsync (), но это происходит до того, как SmtpClient завершил физическую отправку электронной почты по сети (это произойдет только с сетью доставка, однако, доставка файлов по существу синхронна с SendAsync ()).

Это почти похоже на ошибку в SmtpClient, потому что OnCompleted должен вызываться только тогда, когда сообщение действительно отправлено.

0 голосов
/ 27 июля 2011

Вы должны поместить свои dims на уровне класса, если вы хотите получить к ним доступ в вашем обратном вызове.

private msg As System.Net.Mail.MailMessage
private hAV As System.Net.Mail.AlternateView 

private sub yoursub
  msg = new System.Net.Mail.MailMessage(..
  hAV = new ...
end sub

Я предполагаю, что AlternateViews.Add просто добавляет ссылку на hAV, объект msg должен быть удален, в то время как hAV автоматически удаляется с помощью GC.

Приветствия

0 голосов
/ 25 апреля 2009

У меня была очень похожая проблема. То же сообщение об ошибке, но немного другая структура кода. В моем случае я избавлялся от объекта mailmessage внутри основной функции. К моменту запуска события OnCompleted объект уже исчез.

Посмотрите на свой код после SendAsync, чтобы увидеть, освобождаете ли вы объект mailmessage. Например, если вы создаете его внутри оператора using, он будет освобожден до запуска асинхронного события.

...