【问题标题】:VB.Net BackgroundWorker and AsyncCancel Not Working CorrectlyVB.Net BackgroundWorker 和 AsyncCancel 无法正常工作
【发布时间】:2016-07-25 03:18:55
【问题描述】:

再次向 StackOverflow 社区问好!

我在使用 BackgroundWorker 和 AsyncCancel 时遇到了一些问题。 BackgroundWorker 只是发送一封电子邮件,但我希望能够报告任务或电子邮件何时发送,并且能够取消发送任务或电子邮件。

问题是点击取消后,继续然后报错,没有取消。

非常感谢任何帮助!

谢谢!

这是我的完整代码减去 cmets 和导入:

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

【问题讨论】:

  • 您遇到的另一个问题是发送邮件可能非常快。可能是用户甚至没有时间取消发送。

标签: vb.net asynchronous backgroundworker


【解决方案1】:

这完全可以正常工作。问题是您没有正确阅读它的工作原理。在BackgroundWorker 上调用CancelAsync(不是AsyncCancel)不会取消任何东西。它所做的只是在BackgroundWorker 对象上设置一个标志。您可以在 DoWork 事件处理程序中测试该标志,如果已设置,则由您停止工作。在您当前的代码中,您在发送电子邮件之前不会测试该标志,因此无论您是否尝试取消,电子邮件都会被发送。

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

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

【讨论】:

  • 感谢 Enigmativity 和 jmcilhinney 的帮助,我会在早上进行调查。
猜你喜欢
  • 1970-01-01
  • 2011-12-10
  • 2013-09-29
  • 1970-01-01
  • 1970-01-01
  • 2015-12-03
  • 2016-03-09
  • 2016-12-01
  • 1970-01-01
相关资源
最近更新 更多