2016-03-22 3 views
0

У меня проблема, когда BackgroundWorker.CancelAsync() не работает. У меня установлен WorkerSupportsCancellation значение TRUE. Я также опросил BackgroundWorker1.CancellationPending в DoWork. Вот пример кода, которого я пытаюсь достичь. У меня есть рабочий цикл рабочего цикла через метку времени и присваивание значения переменной Measurement. У меня есть подпрограмма, которая запрашивает последнюю указанную переменную Measurement и записывает в listbox. После 5 циклов я посылаю BackgroundWorker.CancelAsync(). Я вижу, что отмена ожидается, но она фактически не отменяет фонового работника. Это условие гонки?vb.net background worker cancel not working

Public Class Form1 

Dim Measurement As String 
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click 

    BackgroundWorker1.RunWorkerAsync() 
    Delay(0.5) 

    For x = 1 To 5 
     ListBox1.Items.Add(Measurement) 
     ListBox1.TopIndex = ListBox1.Items.Count - 1 
     TextBox1.Text = BackgroundWorker1.CancellationPending 
     Delay(1) 
    Next 

    BackgroundWorker1.CancelAsync() 

    TextBox1.Text = BackgroundWorker1.CancellationPending 
    ListBox1.Items.Add("Cancel Pend: " & BackgroundWorker1.CancellationPending) 
    Delay(5) 
    ListBox1.Items.Add("Busy: " & BackgroundWorker1.IsBusy) 

End Sub 

Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 

    If BackgroundWorker1.CancellationPending = True Then 
     e.Cancel = True 
     BackgroundWorker1.Dispose() 
     Exit Sub 
    Else 
     Do 
      Measurement = Now() 
     Loop 
    End If 

End Sub 

End Class

+2

Переместить (или скопировать) чек для отмены внутри цикла – Steve

+0

Вау ... не могу поверить, что я пропустил это ... спасибо Стив! – HurstOlds

+0

@HurstOlds Что происходит, когда вы снова нажимаете кнопку? Если 'BackgroundWorker1.Dispose()' на месте ... Я знаю, что происходит :) – Codexer

ответ

1

Вам просто нужно переместить чек на отмену внутри Do ... Loop в противном случае она будет проверена только в начале обработчика событий DoWork и никогда после этого

Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 

    If BackgroundWorker1.CancellationPending = True Then 
     e.Cancel = True 
     BackgroundWorker1.Dispose() 
    Else 
     Do 
      If BackgroundWorker1.CancellationPending = True Then 
      e.Cancel = True 
      BackgroundWorker1.Dispose() 
      Exit Do 
      Else 
      Measurement = Now() 
      End If 
     Loop 
    End if 
End Sub