2014-07-17 17 views
1

夥計們,我有一個vb.net應用程序,我在其中按下按鈕時啓動後臺工作程序。 BGW永遠在一個Do循環中工作,除非我按另一個按鈕,在這種情況下它應該被停止,執行一些其他工作,然後BGW重新開始。如何正確取消永久生效的後臺工作人員?

我有兩個版本的代碼到目前爲止,基於在線研究,這兩種工作雖然給出不同的結果。到目前爲止的代碼是:

我工作了
Dim autoEvent As New AutoResetEvent(False) 
Private Sub StartWorkerButton_Click() Handles StartWorkerButton.Click 
    MyWorker.WorkerSupportsCancellation = True 
    MyWorker.WorkerReportsProgress = True 
    MyWorker.RunWorker.Asunc() 
End Sub 

Private Sub MyWorker_ProgressChanged() Handles MyWorker.Progresschanged 
    'Update some text boxes text string here based on data from the BGW work 
End Sub 

Private Sub StopThenRestartButton_Click Handles StopThenRestartButton.Click 
    If MyWorker.IsBusy Then 
     MyWorker.CancelAsync() 
     autoEvent.WaitOne() 
     ' Do some work here 
     MyWorker.RunWorkerAsync() ' Restart BGW - But this fails! 
    Else 
     ' Do same work here but without stopping and restarting BGW 
    End If 
Exit Sub 

Private Sub MyWorker_DoWork() Handles MyWorker.DoWork 
    Do While 1 
     If MyWorker.CancellationPending = True 
      e.Cancel = True 
      autoEvent.set 
      Exit Sub 
     Else 
      ' Do some task work over and over again 
      'ReportProgress() here as well 
     End If 
End Sub 

無論怎樣,好像執行可以請求取消,設置的事件,而是因爲它似乎仍然運行則不會重新啓動BGW。克。

+1

代碼如果真的作品'永遠'然後有什麼可以做;) –

+0

你應該使用'退出雖然'而不是'Exit Sub'並將'autoEvent.set'移動到'End Sub之前的while循環之外。 – bansi

+0

您應該有一個名爲'restartWorker'的布爾變量,如果爲true,則在RunWorkerCompleted事件中重新啓動worker(檢查e.Cancelled屬性)。看起來您只希望在StopThenRestart方法中再次調用RunWorkerAsync時完成該工作。 – LarsTech

回答

0

您應該允許在主線程上進行事件處理,並等待Worker完成。其實你不需要autoEvent

Private Sub StopThenRestartButton_Click() Handles StopThenRestartButton.Click 

    If MyWorker.IsBusy Then 
     MyWorker.CancelAsync() 
     autoEvent.WaitOne() 
     While MyWorker.IsBusy 
      'Process the events 
      Application.DoEvents() 
     End While 
     ' Do some work here 
     MyWorker.RunWorkerAsync() ' Restart BGW 
    Else 
     ' Do same work here but without stopping and restarting BGW 
    End If 

End Sub 

這裏是沒有autoEvent

Private Sub StartWorkerButton_Click() Handles StartWorkerButton.Click 
    MyWorker.WorkerSupportsCancellation = True 
    MyWorker.WorkerReportsProgress = True 
    MyWorker.RunWorkerAsync() 
End Sub 

Private Sub MyWorker_ProgressChanged() Handles MyWorker.ProgressChanged 
    'Update some text boxes text string here based on data from the BGW work 
End Sub 

Private Sub MyWorker_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles MyWorker.RunWorkerCompleted 
    Console.WriteLine("RunWorkerCompleted Called") 

End Sub 


Private Sub StopThenRestartButton_Click() Handles StopThenRestartButton.Click 
    If MyWorker.IsBusy Then 
     MyWorker.CancelAsync() 
     While MyWorker.IsBusy 
      Application.DoEvents() 
     End While 
     Console.WriteLine("Worker Finished. Going to restart") 

     ' Do some work here 
     MyWorker.RunWorkerAsync() ' Restart BGW 
    Else 
     ' Do same work here but without stopping and restarting BGW 
    End If 
End Sub 

Private Sub MyWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles MyWorker.DoWork 
    Do While 1 
     If MyWorker.CancellationPending = True Then 
      e.Cancel = True 
      Exit Do ' Exit Sub also works here, if you have nothing to do after the loop 
     Else 
      ' Do some task work over and over again 
      'ReportProgress() here as well 
     End If 
    Loop 
End Sub 
+0

'Application.DoEvents()'! FTW – Toby