.net smtp sendasync with alternateviewsを廃棄した例外をスローします
-
13-09-2019 - |
質問
私は非同期に電子メールを送信しようとしていますが、電子メールに添付されている代替ビューがない限り、それは正常に機能します。別のビューがある場合、次のエラーが表示されます。
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
解決
これが機能していない理由は、sendasync()メソッドが完了したときに導入されたハンドラーが呼び出されているためですが、それはSMTPCLIENTがネットワーク全体で物理的に電子メールの送信を終了する前にあるようです(ただし、これはネットワーク配信でのみ発生しますが、ファイル配信は、本質的にsendasync()と同期しています。
これは、smtpclientのバグのように思えます。これは、メッセージが本当に送信されたときにのみ呼び出される必要があるためです。
他のヒント
私は非常に似たような問題がありました。同じエラーメッセージですが、わずかに異なるコード構造。私の場合、私はメイン関数内のMailMessageオブジェクトを処分していました。コンプレットされたイベントが実行されるまでに、オブジェクトはすでになくなっていました。
sendasyncの後にコードを見て、mailmessageオブジェクトを解放しているかどうかを確認してください。たとえば、使用ステートメント内で作成している場合、Asyncイベントが実行される前に解放されます。
コールバックにアクセスしたい場合は、DIMをクラスレベルに配置する必要があります。
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オブジェクトはGCによって自動的に処分されている間に処分する必要があります。
乾杯
所属していません StackOverflow