.NET SMTP SENDAsync mit alternateViews löst entsorgte Ausnahme aus
-
13-09-2019 - |
Frage
Ich versuche, E-Mails asynchron zu senden, und es funktioniert einwandfrei, solange es keine alternative Aussicht an der E-Mail gibt. Wenn es eine alternative Ansicht gibt, erhalte ich den folgenden Fehler:
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)
Hier ist ein Beispielcode:
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
Und der Rückruf .....
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
Lösung
Der Grund, warum dies nicht funktioniert, liegt darin, dass Ihr aufgeschlossener Handler aufgerufen wird, wenn die SendaSync () -Methode abgeschlossen ist. Dies scheint jedoch zu sein, bevor der SMTPClient die E -Mail physisch über das Netzwerk gesendet hat (dies wird jedoch nur mit Netzwerkbereitstellung geschehen. Dateilieferungen sind im Wesentlichen synchron mit sendaSync ()).
Dies scheint fast ein Fehler im SMTPClient zu sein, da eine Einführung wirklich nur aufgerufen werden sollte, wenn die Nachricht wirklich gesendet wurde.
Andere Tipps
Ich hatte ein sehr ähnliches Problem. Gleiche Fehlermeldung, aber eine etwas andere Codestruktur. In meinem Fall habe ich das MailMessage -Objekt innerhalb der Hauptfunktion entsäuert. Als das aufkommene Ereignis lief, war das Objekt bereits verschwunden.
Sehen Sie sich Ihren Code nach dem SendaSync an, um festzustellen, ob Sie das MailMessage -Objekt befreien. Wenn Sie es beispielsweise in einer Verwendungsanweisung erstellen, wird es vor dem Ausführen des Async -Ereignisses befreit.
Sie sollten Ihre Dims auf Klassenebene einsetzen, wenn Sie in Ihrem Rückruf darauf zugreifen möchten.
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
Ich vermute, dass AlternateViews.add lediglich eine Referenz von HAV hinzufügt, wobei das MSG -Objekt entsendet wird, während der HAV automatisch vom GC entsorgt wird.
Prost