后台工作者CancelAsync()无法正常工作 [英] Backgroundworker CancelAsync() won't work

查看:124
本文介绍了后台工作者CancelAsync()无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用WorkerClass.bw.CancelAsync()取消我的Backgroundworker.但是,它根本不起作用.

I am trying to cancel my Backgroundworker with WorkerClass.bw.CancelAsync(). But it wont work at all.

//编辑!我在这里发布了完整的代码.希望这会有所帮助. 好的,我添加了一些Msgboxes来了解Worker是否仍在忙,而有线连接是,当Worker正在执行操作时得到false!?!?

//edit! I posted the full Code here. May this will help. Okay, i added some Msgboxes to know if the Worker is still busy and the wired thing is, that i get a false while the worker is doing things!?!?

Public Class Form1

Private Sub btn_start_click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_start.Click
        Dim WorkerClass As New BGWClass
        WorkerClass.bw.WorkerSupportsCancellation = True
        WorkerClass.bw.WorkerReportsProgress = True
        If btn_start.Text = "Start" Then
            btn_start.Image = My.Resources.Resources.gem_remove
            btn_add_addy.Enabled = False
            btn_start.Text = "Stop"
            WorkerClass.Start()
            WorkerClass.bw.RunWorkerAsync()
            MsgBox(WorkerClass.bw.IsBusy & " " & WorkerClass.bw.WorkerSupportsCancellation)
        Else
            btn_start.Image = My.Resources.Resources.error_fuck
            btn_add_addy.Enabled = True
            btn_start.Enabled = False
            MsgBox(WorkerClass.bw.IsBusy & " " & WorkerClass.bw.WorkerSupportsCancellation)
            WorkerClass.bw.CancelAsync()
        End If
    End Sub
End Class

Public Class BGWClass
    Public bw As BackgroundWorker = New BackgroundWorker

    Sub Start()
        AddHandler bw.DoWork, AddressOf bw_DoWork
        AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged
        AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted
    End Sub

    Private Sub bw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
         For x As Integer = 1 To 15
            If bw.CancellationPending Then
                e.Cancel = True
                Exit Sub
            End If
            bw.ReportProgress(x)
            Threading.Thread.Sleep(1000)
        Next
    End Sub

    Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs)
        Dim myObject As Object = e.UserState
        Form1.Prgs_error.Text = "- Error: " + e.ProgressPercentage.ToString
    End Sub

    Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
        '...
    End Sub
End Class

推荐答案

我认为您的问题是,在bw_DoWork方法开始时,您仅对CancellationPending进行了一次评估.由于实际上并没有取消BackgroundWorker的方法,因此CancellationPending始终为false,并且永远不会中断工作.调用CancelAsync时,BackgroundWorker不会使用任何魔术来接管程序计数器.

I think your problem is that you are only evaluating CancellationPending once, at the start of your bw_DoWork method. Since there's not really a way to cancel the BackgroundWorker before it starts, CancellationPending will always be false and will never interrupt the work. The BackgroundWorker doesn't use some magic to take over the program counter when you call CancelAsync.

为此,DoWork方法的核心逻辑必须以允许频繁轮询CancellationPending的方式实现,以便代码确切知道何时退出哪些内容.它在做.您将需要执行以下操作:

In order for this to work, the core logic of your DoWork method will have to be implemented in a way that allows for the frequent polling of CancellationPending so that the code will know exactly when to exit out of what it's doing. You will need to go from this:

Private Sub bw_DoWork(ByVal sender As Object, 
                      ByVal e As System.ComponentModel.DoWorkEventArgs)

    If bw.CancellationPending = True Then
        e.Cancel = True
    Else
        'do stuff here
    End If

End Sub

更像这样:

Private Sub bw_DoWork(ByVal sender As Object, 
                      ByVal e As System.ComponentModel.DoWorkEventArgs)

    Dim workIsCompleted As Boolean = False
    While (Not bw.CancellationPending) AndAlso (Not workIsCompleted) Then

        ' Do stuff here, but incrementally so that the while loop can
        ' periodically check to see if CancelAsync has been called.
        ' Also, be sure to set workIsCompleted = True when the work is done.
        ' Otherwise, you will just spin forever until someone cancels it
        ' (Which may or may not be a bad thing, depending on your requirements)

    End While

End Sub

这篇关于后台工作者CancelAsync()无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆