VB.Net BackgroundWorker和AsyncCancel无法正常工作

时间:2016-07-25 03:18:55

标签: vb.net asynchronous backgroundworker

再次问好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

1 个答案:

答案 0 :(得分:1)

这是完全正常的。问题是你还没有正确地阅读它是如何工作的。在CancelAsync上拨打AsyncCancel(非BackgroundWorker)不会取消任何内容。它只是在BackgroundWorker对象上设置了一个标志。您可以在DoWork事件处理程序中测试该标记,如果已设置,则可以停止工作。在您当前的代码中,您在发送电子邮件之后才会测试该标记,因此无论您是否尝试取消,都会发送电子邮件。

您高估了取消BackgroundWorker可以取得的成就。 BackgroundWorker本身并不知道您在DoWork事件处理程序中正在执行的操作,因此它不会简单地中止它。它使您有机会在代码中的适当位置终止任务。如果没有合适的点,那么你就无法取消任何东西。

在您的情况下,一旦您在Send上致电SmtpClient,您就无法执行任何操作,直到该同步方法返回,因此您无法取消它。您应该做的不是使用BackgroundWorker,而是使用SmtpClient类中内置的异步功能。它有SendAsync方法和SendAsyncCancel方法,因此您可以让它为您处理多线程。