我有一些困難處理停止,然後啓動後臺工作人員使用VB.net時,只有一個非常小的時間間隔CancelAsync()調用和RunWorkerAsync( )電話。我已經創建了一個例子來說明下面的問題。如果單擊按鈕一次,然後快速連續單擊兩次,則會出現此示例中的問題。實質上,據我所知,問題在於後臺工作者仍在循環遍歷for循環(包含模仿需要一些時間運行的代碼),並且還沒有機會檢查是否有待取消。停止,然後快速連續啓動相同的後臺工作
我試圖使用的解決方案是等待後臺工作者關閉,然後再次啓動工人。但是,這個while循環會無限地迭代 - 後臺工作人員永遠不會終止。我假設讓主線程進入睡眠狀態也會讓後臺工作線程進入休眠狀態。它是否正確?
問題:當檢查一個掛起的取消不能合理地更頻繁地執行時,什麼是停止後臺工作者的建議方式,然後可能需要在幾秒鐘後重新啓動它?
建議和意見非常感謝。
Public Class Form1
Dim WithEvents bgWorker As System.ComponentModel.BackgroundWorker = New System.ComponentModel.BackgroundWorker
Friend WithEvents startStopButton As Button = New Button
Dim workerShouldBeRunning As Boolean = False
Sub startStopButton_click() Handles startStopButton.Click
If workerShouldBeRunning Then
bgWorker.CancelAsync()
Else
While bgWorker.IsBusy
Threading.Thread.Sleep(1)
End While
bgWorker.RunWorkerAsync()
End If
workerShouldBeRunning = Not workerShouldBeRunning
End Sub
Sub bgWorker_doWork() Handles bgWorker.DoWork
While Not bgWorker.CancellationPending
Dim sum As Long
For counter = 1 To 100000
sum += counter
Next
Threading.Thread.Sleep(1000)
End While
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
startStopButton.Location = New Point(10, 100)
startStopButton.Size = New System.Drawing.Size(200, 23)
startStopButton.Text = "Click" 'Click to start or stop the background dummy process.
Me.Controls.Add(startStopButton)
bgWorker.WorkerSupportsCancellation = True
End Sub
End Class
編輯:
用羅斯壓的建議,我提高了示例代碼。雖然解決方案似乎有點不好。
Public Class Form1
Dim WithEvents bgWorker As System.ComponentModel.BackgroundWorker = New System.ComponentModel.BackgroundWorker
Friend WithEvents startStopButton As Button = New Button
Dim workerShouldBeRunning As Boolean = False
Dim startQueued As Boolean = False
Sub startStopButton_click() Handles startStopButton.Click
If workerShouldBeRunning Then
bgWorker.CancelAsync()
Else
If bgWorker.IsBusy Then
startQueued = True
Else
bgWorker.RunWorkerAsync()
End If
End If
workerShouldBeRunning = Not workerShouldBeRunning
End Sub
Sub bgWorker_doWork() Handles bgWorker.DoWork
While Not bgWorker.CancellationPending
Dim sum As Long
For counter = 1 To 100000
sum += counter
Next
Threading.Thread.Sleep(1000)
End While
End Sub
Sub bgWorkerCompleted() Handles bgWorker.RunWorkerCompleted
If startQueued Then
startQueued = False
bgWorker.RunWorkerAsync()
End If
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
startStopButton.Location = New Point(10, 100)
startStopButton.Size = New System.Drawing.Size(200, 23)
startStopButton.Text = "Click" 'Click to start or stop the background dummy process.
Me.Controls.Add(startStopButton)
bgWorker.WorkerSupportsCancellation = True
End Sub
End Class
如果BackgroundWorker的當前運行然後取消被擊中時禁用按鈕。在RunWorkerCompleted()事件中重新啓用它。 –
@空閒心感謝您的評論。我相信這會比解決方案更具解決方法,但我認爲我可以暫時處理這個問題。 – Sepia
您正試圖「按住」按鈕點擊處理程序中的代碼,直到發生其他一些事件。這是一個禁止...... –