gpt4 book ai didi

vb.net - 快速连续停止然后启动同一个后台工作程序

转载 作者:行者123 更新时间:2023-12-02 21:47:09 25 4
gpt4 key购买 nike

当 CancelAsync() 调用和 RunWorkerAsync() 调用之间只有非常小的间隔时,我在使用 VB.net 停止然后启动后台工作程序时遇到一些困难。我创建了一个例子来说明下面的问题。如果单击按钮一次然后快速连续单击两次,则会出现此示例中的问题。本质上,据我了解,问题在于后台工作人员仍在迭代 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

编辑:

根据 Ross Presser 的建议,我改进了示例代码。不过,这个解决方案似乎有点糟糕。

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

最佳答案

这种方法怎么样?...我们只需用新的后台 worker 替换旧的后台 worker :

Public Class Form1

Private WithEvents startStopButton As Button = New Button
Private WithEvents bgWorker As System.ComponentModel.BackgroundWorker = Nothing

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)
End Sub

Private Sub startStopButton_click() Handles startStopButton.Click
If IsNothing(bgWorker) Then
Static bgwCounter As Integer = 0
bgwCounter = bgwCounter + 1
bgWorker = New System.ComponentModel.BackgroundWorker
bgWorker.WorkerSupportsCancellation = True
bgWorker.RunWorkerAsync(bgwCounter)
Else
bgWorker.CancelAsync()
bgWorker = Nothing
End If
End Sub

Private Sub bgWorker_doWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgWorker.DoWork
Dim bgwCounter As Integer = e.Argument
Debug.Print("Running #" & bgwCounter)
Dim bgw As System.ComponentModel.BackgroundWorker = sender
While Not bgw.CancellationPending
Dim sum As Long
For counter As Integer = 1 To 100000
sum += counter
Next

Threading.Thread.Sleep(1000)
End While
Debug.Print("Cancelled #" & bgwCounter)
End Sub

End Class

关于vb.net - 快速连续停止然后启动同一个后台工作程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19328182/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com