【发布时间】:2016-06-19 01:49:20
【问题描述】:
该应用程序的功能远不止于此,但我已通过以下示例缩小了问题范围。
当bgwDone.WaitOne()被注释掉时,进度条工作正常,取消按钮有效,但在后台进程完成之前继续执行。
在应用bgwDone.WaitOne()时,ProgressForm是可见的,但没有启用,所以不能取消处理,进度条不刷新,而且最混乱的部分,Msgbox("1") 不执行。我只在后台工作人员完成后看到 Msgbox("2") 。我完全迷惑了。
Imports System.ComponentModel
Public Class Form1
Private WithEvents bgw As BackgroundWorker
Private Event bgwCancelled()
Private bgwDone As New System.Threading.AutoResetEvent(False)
'Allows ProgressForm to cancel execution
Public Sub bgwCancelAsync()
RaiseEvent bgwCancelled()
End Sub
Private Sub bgw_Cancelled_by_ProgressForm() Handles Me.bgwCancelled
bgw.CancelAsync()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Cursor = Cursors.WaitCursor
bgw = New BackgroundWorker
bgw.WorkerReportsProgress = True
bgw.WorkerSupportsCancellation = True
If bgw.IsBusy = False Then
ProgressForm.Show()
bgw.RunWorkerAsync(10)
End If
'********THIS LINE: bgwDone.WaitOne() MAKES A BIG DIFFERENCE*******
bgwDone.WaitOne()
MsgBox("1")
MsgBox("2")
Cursor = Cursors.Default
End Sub
'BackgroundWorker.RunWorkerAsync raises the DoWork event
Private Sub bgw_DoWork(sender As Object, e As DoWorkEventArgs) Handles bgw.DoWork
Dim numToDo As Integer = CInt(e.Argument)
For n As Integer = 1 To numToDo
If bgw.CancellationPending Then
Exit For
End If
System.Threading.Thread.Sleep(200)
bgw.ReportProgress(n * 10)
Next
bgwDone.Set()
End Sub
'ReportProgress raises the ProgressChanged event
Private Sub bgw_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles bgw.ProgressChanged
ProgressForm.UpdateProgress(e.ProgressPercentage)
End Sub
Private Sub bgw_RunWorkerCompleted(sender As Object,
e As RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
ProgressForm.Close()
End Sub
还有我的带有 ProgressBar 的表单:
Public Class ProgressForm
Private Sub ButtonCancel_Click(sender As Object, e As EventArgs) Handles ButtonCancel.Click
Form1.bgwCancelAsync()
End Sub
Public Sub UpdateProgress(pct As Integer)
ProgressBar1.Value = pct
ProgressBar1.Refresh()
End Sub
End Class
【问题讨论】:
-
了解您要做什么可能会有所帮助。您正在 UI 线程上调用
WaitOne,这看起来很奇怪。如果您想在DoWork中模拟长时间运行的任务,请将 Sleep 和 Report 放入循环中,否则它们只会发生一次。此外,您似乎正在使用默认表单实例(即类名,Form1和ProgressForm),这通常是线程的问题。 -
@Plutonix 睡眠和报告在循环中。没有
WaitOne,报告工作正常。我的实际应用是解析 CNC G 代码,进行更改。实际上没有用于生产用途的 GUI,仅用于初始设置和测试。文件名作为命令行参数提供给它。它按原样工作正常,但我认为添加进度条会很好,因为较大的文件需要几秒钟。ProgressForm这个名字怎么会惹麻烦? -
是的,它们在循环内。抱歉,我想我当时累了和/或饿了。
标签: vb.net progress-bar backgroundworker