Pregunta

Estoy tratando de enviar correos electrónicos de forma asincrónica y funciona bien siempre que no haya una vista alternativa adjunta al correo electrónico. Cuando hay una vista alternativa, recibo el siguiente error:

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)

Aquí hay algún código de muestra:

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

Y la devolución de llamada .....

 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
¿Fue útil?

Solución

La razón por la que esto no funciona es porque su controlador OnCompleted se llama cuando se completa el método sendasync (), pero eso parece ser antes de que el smtpclient haya terminado de enviar físicamente el correo electrónico a través de la red (esto solo sucederá con la entrega de la red, aunque, aunque, aunque, aunque, aunque, aunque, aunque, aunque, aunque, aunque, aunque la entrega de la red. Las entregas de archivos son esencialmente sincrónicas con sendAsync ()).

Esto casi parece un error en el SMTPClient porque OnCompleted realmente solo debería llamarse cuando el mensaje realmente se ha enviado.

Otros consejos

Tuve un problema muy similar. Mismo mensaje de error, pero una estructura de código ligeramente diferente. En mi caso, estaba deshaciendo del objeto MailMessage dentro de la función principal. Cuando se ejecutó el evento OnCompleted, el objeto ya se había ido.

Mire su código después del SendAsync para ver si está liberando el objeto MailMessage. Por ejemplo, si lo está creando dentro de una declaración de uso, se liberará antes de que se ejecute el evento Async.

Debe poner sus dims en el nivel de clase si desea acceder a ellos en su devolución de llamada.

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

Supongo que alternateViews.Add simplemente agrega una referencia de HAV, el objeto MSG necesita deshacerse mientras el HAV está dispuesto automáticamente por el GC ..

Salud

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top