2013-06-03 4 views
4

Я пытаюсь отменить мой фоновой рабочий с WorkerClass.bw.CancelAsync(). Но это вообще не будет работать.Фоновый работник ОтменитьAsync() не работает

// редактировать! Я разместил здесь полный код. Пусть это поможет. Хорошо, я добавил некоторые Msgboxes, чтобы узнать, все ли занят Рабочий и что связано с проводкой, что я получаю false, пока рабочий делает что-то!?!?

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 
+1

Установили ли вы 'WorkerClass.bw.WorkerSupportsCancellation = true'? В противном случае он ничего не отменит. –

+0

Не могли бы вы поместить весь код рабочего стола, пожалуйста? – Marshall777

+0

Я сделал. Не могли бы вы снова взглянуть на это =)? – Ponch0

ответ

4

Я думаю, ваша проблема в том, что вы только оценки CancellationPending один раз, в начале вашего метода bw_DoWork. Поскольку на самом деле нет способа отменить BackgroundWorker до его начала, CancellationPending всегда будет ложным и никогда не прерывает работу. BackgroundWorker не использует магию для захвата счетчика программ при вызове CancelAsync.

Для того, чтобы это сработало, основная логика вашего метода DoWork должна быть реализована таким образом, чтобы обеспечить частый опрос CancellationPending, чтобы код точно знал, когда нужно выйти из того, что он делает. Вам нужно будет идти из этого:

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 
3

Основная модель BackgroundWorker. Это так, как вы выглядите.

Dim WithEvents worker As New System.ComponentModel.BackgroundWorker 

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
    'start 
    If Not worker.IsBusy Then 
     worker.WorkerReportsProgress = True 
     worker.WorkerSupportsCancellation = True 
     worker.RunWorkerAsync() 
    End If 
End Sub 

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 
    'cancel 
    If worker.IsBusy AndAlso worker.WorkerSupportsCancellation Then 
     worker.CancelAsync() 
    End If 
End Sub 

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

Private Sub foo_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles worker.ProgressChanged 
    Label1.Text = e.ProgressPercentage.ToString 
End Sub 

Private Sub foo_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles worker.RunWorkerCompleted 
    If e.Cancelled Then 
     Label1.Text = "canceled" 
    ElseIf Not IsNothing(e.Error) Then 
     Label1.Text = "error " & e.Error.Message 
    Else 
     Label1.Text = "done" 
    End If 
End Sub 
+0

Не совсем, но mostoly это должно быть таким же, как мой код. Все работы относятся к 'CancelAsync()' – Ponch0

+0

. Хорошо, я попытался отредактировать мой с вашим, и я всегда получаю логическое значение false для 'worker.IsBusy'. Не знаете, почему, потому что рабочий работает ?! – Ponch0

+0

Вероятно, существует задержка с момента вызова RunWorkerAsync до того, как фактический рабочий стол начнет работу и обновит свойство до «True». Требуется время, чтобы создать новый поток и начать выполнение кода. Следующая строка, где вы проверяете 'IsBusy' (снова, один раз и только один раз), вероятно, произойдет до того, как все это завершится. Если вы произведете какую-то произвольную задержку (скажем, 3000 мс), это, вероятно, сработает. – mclark1129

Смежные вопросы