无法使用 .SendAsync 发送但使用 SmtpClient_Send 的电子邮件

Emails failing to send with .SendAsync but work with SmtpClient_Send

我一直在 vb.net 中编写电子邮件功能,当我的代码是 Smtp_Server.Send 时它工作正常,电子邮件发送成功没有问题。

然后,我不得不将其更改为 SmtpServer_SendAsync,并且我能够使用 中关于如何记录任何电子邮件的信息来做到这一点。

然而,当尝试使用以下代码发送电子邮件时,它总是失败,但将其改回 .Send 没有任何问题。我是否在电子邮件代码中遗漏了其他内容?

设置和发送电子邮件的代码是这样的:(显然我也有设置变量的代码,但它在这里不相关,所以我把它省略了)

Smtp_Server.UseDefaultCredentials = False
Smtp_Server.Credentials = New Net.NetworkCredential(senderAdd, senderPass)
Smtp_Server.EnableSsl = False
Smtp_Server.Host = SMTPserver

Try
   AddHandler Smtp_Server.SendCompleted, AddressOf sendComplete
Catch ex As Exception
    silentErrorLog(ex)
End Try

e_mail = New MailMessage()
e_mail.From = New MailAddress(senderAdd)
e_mail.DeliveryNotificationOptions = DeliveryNotificationOptions.OnSuccess
e_mail.To.Add(eMail)
e_mail.Subject = subj
e_mail.IsBodyHtml = False
e_mail.Body = bod

Dim userState As Object = e_mail
Smtp_Server.SendAsync(e_mail, userState)

e_mail.Dispose()
e_mail = Nothing

Try
   If bInvoice = True Then
       triggerInvoice()
   End If

 Catch ex As Exception
      silentErrorLog(ex)
 End Try

 Catch ex As Exception
    errorLog(ex)

 End Try
End Sub

这个错误是

Failure sending email

Inner Exception: Cannot access a disposed object

sendComplete

代码
Public Sub sendComplete(ByVal sender As Object, e As AsyncCompletedEventArgs)

 Try
   If e.Error IsNot Nothing Then
     PictureBox1.Visible = False
     MsgBox("Failed to send email!", MessageBoxIcon.Warning + MsgBoxStyle.OkOnly, "Error")
     mailSent = False

它总是使用 If 的第一部分,从不使用 Else 子句,所以一定是哪里出了问题?

您在调用 SendAsync 后立即处理电子邮件。但是,此时消息尚未发送,因此您处置 SendAsync 仍需要的对象:

Smtp_Server.SendAsync(e_mail, userState)

e_mail.Dispose()    ' bad timing

解决方法是attach to the SendCompleted event and dispose the message there。您可以使用 lambda 表达式来确保 e_mail 变量在事件处理程序的范围内:

AddHandler Smtp_Server.SendCompleted, Sub(sender, e) e_mail.Dispose()

Smtp_Server.SendAsync(e_mail, userState)

或者,由于您将消息作为用户状态传递给您的异步方法,您可以在现有的事件处理程序中处理该消息:

Public Sub sendComplete(ByVal sender As Object, e As AsyncCompletedEventArgs)
    DirectCast(e.UserState, MailMessage).Dispose()
    ...
End Sub