[英]VB.net - Progressbar using BackgroundWorker
I am trying to implement a progressbar using BackgroundWorker. 我正在尝试使用BackgroundWorker实现进度条。
But the progress bar hides itself after a second and it doesn't remain on top till end. 但是进度条会在一秒钟后隐藏起来,并且不会一直停留到最后。 Not sure why.
不知道为什么。
Below is my code in form: 下面是我的代码形式:
Private Sub btnProgressBarPOC_Click(sender As Object, e As EventArgs) Handles btnProgressBarPOC.Click
BackgroundWorker = New BackgroundWorker()
BackgroundWorker.WorkerReportsProgress = True
autoResetEvent = New AutoResetEvent(False)
ProgressBar = New frmProgressBar(BackgroundWorker)
ProgressBar.ShowDialog()
autoResetEvent.WaitOne()
MsgBox("Main Done", vbInformation)
End Sub
Sub Processing() Handles BackgroundWorker.DoWork
BackgroundWorker.ReportProgress(33)
Threading.Thread.Sleep(5000)
BackgroundWorker.ReportProgress(66)
Threading.Thread.Sleep(5000)
BackgroundWorker.ReportProgress(100)
MsgBox("Background Done", vbInformation)
AutoResetEvent.Set()
End Sub
And below is my code in for which contains progressbar: 下面是我的代码,其中包含进度条:
Imports System.ComponentModel
Public Class frmProgressBar
Private WithEvents _BGW As System.ComponentModel.BackgroundWorker
Private _TaskInProgress As String
Public WriteOnly Property TaskInProgress()
Set(value)
_TaskInProgress = value
_BGW.ReportProgress(1)
End Set
End Property
Public Sub New(ByVal BGW As System.ComponentModel.BackgroundWorker)
_BGW = BGW
InitializeComponent()
End Sub
Private Sub frmProgress_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
If Not IsNothing(_BGW) Then
_BGW.RunWorkerAsync()
End If
End Sub
Private Sub _BGW_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles _BGW.ProgressChanged
progressBar.Value = e.ProgressPercentage
If Me.Text <> _TaskInProgress Then
Me.Text = _TaskInProgress
End If
End Sub
Private Sub _BGW_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles _BGW.RunWorkerCompleted
Me.Close()
_TaskInProgress = ""
End Sub
'Private Sub _BGW_DoWork(sender As Object, e As DoWorkEventArgs) Handles _BGW.DoWork
' Do While True
' ' Has the background worker be told to stop?
' If _BGW.CancellationPending Then
' ' Set Cancel to True
' e.Cancel = True
' Exit Do
' End If
' System.Threading.Thread.Sleep(2000) ' Sleep for 1 Second
' Loop
'End Sub
End Class
I have uploaded my project here: https://drive.google.com/file/d/0B7gzonuQsNbvaDZvR3ltSl9WNTg/view?usp=sharing
我已经在这里上传了我的项目: https : //drive.google.com/file/d/0B7gzonuQsNbvaDZvR3ltSl9WNTg/view?usp=sharing
You don't need the AutoReset event as you can handle the RunWorkerCompleted event. 您不需要AutoReset事件,因为您可以处理RunWorkerCompleted事件。 Currently you are blocking the UI thread.
当前,您正在阻止UI线程。
Remove the msgbox from RunWorkerAsync as well as this should be handled on your ui thread. 从RunWorkerAsync中删除msgbox,这应该在您的ui线程上进行处理。
I suspect its an exception that is causing the RunWorkerAsync to exit so inspect the error code in the RunWorkerCompleted event. 我怀疑它是导致RunWorkerAsync退出的异常,因此请检查RunWorkerCompleted事件中的错误代码。 This is probably caused by your TaskInProgress property which through a roundabout way is interacting with the textbox despite being on the Background thread.
这可能是由TaskInProgress属性引起的,尽管该属性位于背景线程中,但该属性仍通过回旋方式与文本框进行交互。
Instead to update the TaskInProgress textbox send it as the extra argument to ReportProgress and get it back from the progress box. 而是要更新TaskInProgress文本框,将其作为额外的参数发送给ReportProgress并从进度框中取回它。
BackgroundWorker.ReportProgress(33, "Hello")
Private Sub _BGW_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles _BGW.ProgressChanged
Me.Text = CStr(e.UserState)
....
Below is the corrected code which worked very well: 以下是更有效的更正代码:
Public Class frmMisc
Private WithEvents BackgroundWorker As BackgroundWorker, ProgressBar As frmProgressBar
Private Sub btnProgressBarPOC_Click(sender As Object, e As EventArgs) Handles btnProgressBarPOC.Click
Call RunProcessing()
MsgBox("Main Done", vbInformation)
End Sub
Sub RunProcessing()
BackgroundWorker = New BackgroundWorker()
BackgroundWorker.WorkerReportsProgress = True
ProgressBar = New frmProgressBar(BackgroundWorker)
ProgressBar.ShowDialog()
End Sub
Sub Processing() Handles BackgroundWorker.DoWork
BackgroundWorker.ReportProgress(33, "Step-1")
Threading.Thread.Sleep(3000)
BackgroundWorker.ReportProgress(66, "Step-2")
Threading.Thread.Sleep(2000)
BackgroundWorker.ReportProgress(100, "Step-3")
End Sub
End Class
Public Class frmProgressBar
Private WithEvents _BGW As System.ComponentModel.BackgroundWorker
Private _TaskInProgress As String
Public Sub New(ByVal BGW As System.ComponentModel.BackgroundWorker)
_BGW = BGW
InitializeComponent()
End Sub
Private Sub frmProgress_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
If Not IsNothing(_BGW) Then
_BGW.RunWorkerAsync()
End If
End Sub
Private Sub _BGW_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles _BGW.ProgressChanged
progressBar.Value = e.ProgressPercentage
Me.Text = e.UserState
End Sub
Private Sub _BGW_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles _BGW.RunWorkerCompleted
Me.Close()
_TaskInProgress = ""
End Sub
End Class
I was doing up Me.Text outside of ProgressChanged even which was causing this issue.
我正在对ProgressChanged之外的Me.Text进行处理,甚至导致了此问题。 Thanks to @Hans for providing hint about this!
感谢@Hans提供有关此提示!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.