I am trying to implement a progressbar using 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
You don't need the AutoReset event as you can handle the RunWorkerCompleted event. Currently you are blocking the UI thread.
Remove the msgbox from RunWorkerAsync as well as this should be handled on your ui thread.
I suspect its an exception that is causing the RunWorkerAsync to exit so inspect the error code in the RunWorkerCompleted event. This is probably caused by your TaskInProgress property which through a roundabout way is interacting with the textbox despite being on the Background thread.
Instead to update the TaskInProgress textbox send it as the extra argument to ReportProgress and get it back from the progress box.
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. Thanks to @Hans for providing hint about this!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.