电子邮件无法使用.SendAsync发送,但可以使用SmtpClient_Send

时间:2017-05-24 08:32:00

标签: vb.net email asynchronous smtpclient

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

然后,我必须将其更改为SmtpServer_SendAsync,并且我能够使用this question中有关如何记录任何电子邮件的信息来执行此操作。

但是,尝试使用以下代码发送电子邮件时,它始终会失败,但将其更改回只有.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

错误是

  

发送电子邮件失败

     

内部异常:无法访问已处置的对象

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子句,所以一定有问题吗?

1 个答案:

答案 0 :(得分:1)

在调用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)

或者,由于您将消息作为usertate传递给异步方法,因此您可以在现有事件处理程序中处理消息:

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