再次问好StackOverflow社区!
我遇到了BackgroundWorker和AsyncCancel的一些问题。 BackgroundWorker只是发送一封电子邮件,但我希望能够在任务或电子邮件发送时报告,并且能够取消发送的任务或电子邮件。
问题是在点击取消后,它会继续,然后报告错误,而不是取消。
非常感谢任何帮助!
谢谢!
这是我的完整代码减去评论和导入:
Private Sub Sendmail_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
StatusLabel.Text &= "Idle"
End Sub
Private Sub SendmailBackgroundWorker_DoWork(sender As Object, e As DoWorkEventArgs) Handles SendmailBackgroundWorker.DoWork
Try
Dim Smtp As New SmtpClient()
Dim Email As New MailMessage()
Smtp.Port = 25
Smtp.Host = "mail.server.com"
Smtp.EnableSsl = False
Smtp.UseDefaultCredentials = False
Smtp.Credentials = New Net.NetworkCredential("user@server.com", "password")
Email = New MailMessage()
Email.From = New MailAddress(FromTextBox.Text)
Email.To.Add(ToTextBox.Text)
Email.Subject = SubjectTextBox.Text
Email.IsBodyHtml = False
Email.Body = BodyTextBox.Text
Smtp.Send(Email)
Catch ex As Exception
MsgBox("Sendmail Error!" & vbNewLine & vbNewLine & ex.ToString)
End Try
If SendmailBackgroundWorker.CancellationPending Then
StatusLabel.Text = "Canceling"
e.Cancel = True
End If
End Sub
Private Sub SendmailBackgroundWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles SendmailBackgroundWorker.RunWorkerCompleted
StatusLabel.Text = "Status: "
If (e.Error IsNot Nothing) Then
StatusLabel.Text &= "Worker Error!" & vbNewLine & vbNewLine & e.Error.Message
ElseIf e.Cancelled Then
StatusLabel.Text &= "Canceled!"
Else
StatusLabel.Text &= "Sent!"
End If
SendButton.Enabled = True
CancelButton.Enabled = False
End Sub
Private Sub SendButton_Click(sender As Object, e As EventArgs) Handles SendButton.Click
StatusLabel.Text = "Status: "
SendButton.Enabled = False
CancelButton.Enabled = True
SendmailBackgroundWorker.WorkerSupportsCancellation = True
SendmailBackgroundWorker.WorkerReportsProgress = True
StatusLabel.Text &= "Sending..."
SendmailBackgroundWorker.RunWorkerAsync()
End Sub
Private Sub CancelButton_Click(sender As Object, e As EventArgs) Handles CancelButton.Click
CancelButton.Enabled = False
SendmailBackgroundWorker.CancelAsync()
End Sub
答案 0 :(得分:1)
这是完全正常的。问题是你还没有正确地阅读它是如何工作的。在CancelAsync
上拨打AsyncCancel
(非BackgroundWorker
)不会取消任何内容。它只是在BackgroundWorker
对象上设置了一个标志。您可以在DoWork
事件处理程序中测试该标记,如果已设置,则可以停止工作。在您当前的代码中,您在发送电子邮件之后才会测试该标记,因此无论您是否尝试取消,都会发送电子邮件。
您高估了取消BackgroundWorker
可以取得的成就。 BackgroundWorker
本身并不知道您在DoWork
事件处理程序中正在执行的操作,因此它不会简单地中止它。它使您有机会在代码中的适当位置终止任务。如果没有合适的点,那么你就无法取消任何东西。
在您的情况下,一旦您在Send
上致电SmtpClient
,您就无法执行任何操作,直到该同步方法返回,因此您无法取消它。您应该做的不是使用BackgroundWorker
,而是使用SmtpClient
类中内置的异步功能。它有SendAsync
方法和SendAsyncCancel
方法,因此您可以让它为您处理多线程。