2009-04-22 9 views
1

Ich versuche, E-Mails asynchron zu senden, und es funktioniert gut, solange kein AlternateView an die E-Mail angehängt ist. Wenn es eine alternative Ansicht ist, bekomme ich folgende Fehlermeldung:.NET SMTP SendAsync mit AlternateViews löst disposed Ausnahme

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("[email protected]", "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 

Antwort

2

Der Grund Dies funktioniert nicht, weil Ihr OnCompleted-Handler aufgerufen wird, wenn die SendAsync() -Methode abgeschlossen ist, aber das scheint zu sein, bevor der SmtpClient die E-Mail physisch über das Netzwerk gesendet hat (dies wird nur möglich sein) Bei der Netzwerkzustellung sind Dateiauslieferungen jedoch im Wesentlichen synchron mit SendAsync()).

Das scheint fast wie ein Fehler im SmtpClient, denn OnCompleted sollte wirklich nur aufgerufen werden, wenn die Nachricht wirklich gesendet wurde.

+0

ich gesendet habe Übermittlung an Microsoft. Wir werden sehen, ob das mich irgendwohin bringt. – hacker

+0

Microsoft antwortete und gab an, dass sie in der Lage waren, es fehlerfrei zu funktionieren. Ich hatte keine Chance, zu dieser Anwendung zurückzukehren, um die E-Mail erneut asynchron anzuwenden und sie zu testen. – hacker

0

Ich hatte ein sehr ähnliches Problem. Die gleiche Fehlermeldung, aber eine etwas andere Codestruktur. In meinem Fall entsorgte ich das mailmessage-Objekt innerhalb der Hauptfunktion. Zu dem Zeitpunkt, als das OnCompleted-Ereignis ausgeführt wurde, war das Objekt bereits gelöscht.

Sehen Sie sich Ihren Code nach dem SendAsync an, um zu sehen, ob Sie das Objekt mailmessage freigeben. Wenn Sie es beispielsweise in einer using-Anweisung erstellen, wird es freigegeben, bevor das asynchrone Ereignis ausgeführt wird.

+0

Ich habe das überprüft, weil ich anfangs die MailMessage im finally-Block hatte. Unglücklicherweise werden die AlternateViews (jetzt überhaupt) nicht entsorgt und die MailMessage wird am Ende des OnCompleted-Blocks entsorgt. Der Fehler tritt auf, bevor es sogar zu dem MailMessage-Dispose-Aufruf gelangt. Eine Sache, an die ich denke, ist, dass der GC das Objekt zu schnell sammelt ... nicht sicher, ob das möglich ist. – hacker

0

Sie sollten Ihre Dims auf Klassenebene setzen, wenn Sie in Ihrem Callback 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 

Meine Vermutung ist, dass AlternateViews.Add fügt lediglich einen Verweis von HAV, die msg Objekt Bedürfnisse verfügen, während die HAV automatisch vom GC angeordnet ist ..

Prost

Verwandte Themen