vb.net backgroundworker CancelAsync不工作

vb.net backgroundworker CancelAsync不工作,vb.net,Vb.net,我在backgroundworker中遇到停止问题,我对backgroundworker使用以下命令: 更新代码 Private Sub UnpackSystem_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles UnpackSystem.DoWork Dim worker As System.ComponentModel.BackgroundWorker =

我在backgroundworker中遇到停止问题,我对backgroundworker使用以下命令:

更新代码

Private Sub UnpackSystem_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles UnpackSystem.DoWork
    Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
    For i As Integer = 1 To 100
        If worker.CancellationPending Then
            e.Cancel = True
            Exit For
        End If
        worker.ReportProgress(i, i & " iterations complete")
        Threading.Thread.Sleep(250)
        Dim oProcess As New Process()
        Dim oStartInfo As New ProcessStartInfo("cmd.exe", "/c bin\Imgtool\simg2img.exe tmp/system.img tmp/system.img.ext4")
        oStartInfo.WindowStyle = ProcessWindowStyle.Hidden
        oStartInfo.CreateNoWindow = True
        oStartInfo.UseShellExecute = False
        oStartInfo.RedirectStandardOutput = True
        oProcess.StartInfo = oStartInfo
        oProcess.Start()
        Dim sOutput As String
        Using oStreamReader As System.IO.StreamReader = oProcess.StandardOutput
            sOutput = oStreamReader.ReadToEnd()
        End Using
        TextBox8.Invoke(Sub() TextBox8.AppendText(Environment.NewLine & sOutput))

    Next i

End Sub

Private Sub UnpackSystem_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles UnpackSystem.ProgressChanged
    Me.ProgressBar5.Value = e.ProgressPercentage
End Sub

Private Sub UnpackSystem_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles UnpackSystem.RunWorkerCompleted
    If e.Cancelled = True Then
        TextBox8.AppendText(Environment.NewLine & "Canceled!")
    ElseIf e.Error IsNot Nothing Then
        TextBox8.AppendText(Environment.NewLine & "Error: " & e.Error.Message)
    Else
        TextBox8.AppendText(Environment.NewLine & "Done!")
    End If
End Sub
并且,我使用以下代码停止backgroundworker进程

Private Sub Button55_Click(ByVal sender As System.Object, ByVal e As EventArgs) Handles Button55.Click
    If Me.UnpackSystem.IsBusy Then
        Me.UnpackSystem.CancelAsync()
    End If
    Dim cmd() As Process
    cmd = Process.GetProcessesByName("cmd")
    If cmd.Count > 0 Then
        Process.GetProcessesByName("cmd")(0).Kill()
    End If
End Sub

但是它没有被取消,我的问题在哪里?

您只是在测试当DoWork事件处理程序首次启动时取消是否处于挂起状态,当然在该阶段不会。为了稍后取消后台任务,您必须实际测试稍后是否有取消挂起


不过这里没有魔法。正如我所说的,为了取消,您必须在DoWork事件处理程序中实际测试取消是否挂起。该测试只能在其他代码行之间进行。调用ReadToEnd方法后,无论用户是否请求取消,您都要将流读取到底。显然,在该调用返回之前,您无法测试挂起的取消。谢谢您能举个例子吗?不幸的是,我没有注意到您不需要另一个示例,因为您已经有了一个示例:您自己的代码。您已经知道如何测试取消是否挂起。我所说的是,如果您希望能够取消在代码中其他位置的工作,那么您需要在代码中的其他位置执行该操作。考虑一下这个。假设你的工作场所有一个布告栏。你开始工作,你要做的第一件事就是检查布告栏,它是空的。如果你一整天都不看布告栏,你会看到有人在午餐时间贴的布告吗?不,你不会的,所以你必须稍后再检查。这是一样的。使用我几年前创建的BackgroundWorker。显示如何处理取消。谢谢我更新了我的第一篇帖子请看。在进行这些更改后,它将不再工作