I’m having trouble getting a progress bar to update. I’d be okay just with a moving marquee bar. Basically, I’m reading a database routine in a SqliteReader.vb class. I’m new to visual basic, and I’m sure I need to use the worker_DoWork routine, but I’m not sure how to expose my variables coming from Form1: graphData, graphComputations, m_debug to the worker_DoWork sub. How is this usually done?
Public Class SqliteReader
Public Sub ReadDataBase
End Sub
End Class
This is updating a graph (zedgraph element) on the main form, Form1.vb. I call the progressbar from the main form like this:
ProgressBar.Initialize(channelArray, computationArray, m_debug)
ProgressBar.vb below:
Partial Public Class ProgressBar
Dim DataAcquisition As New SqliteReader
Dim WithEvents worker As New BackgroundWorker
Public Sub Initialize(ByRef graphData As Channels(), ByRef graphComputations As Computations(), ByVal m_debug As Integer)
DataAcquisition = SqliteReader.GetInstance()
Me.Show()
Me.Update()
Dim Update_Thread As Thread(AddressOf Update_ThreadExecute)
Update_Thread.Priority = ThreadPriority.Normal
Update_Thread.Start()
DataAcquisition.ParseEntireDatabase(graphData, graphComputations, m_debug)
Me.Close()
End Sub
Private Sub ProgressBarStart(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DataAcquisition = SqliteReader.GetInstance()
progress.Style = ProgressBarStyle.Marquee
worker.WorkerReportsProgress = True
worker.WorkerSupportsCancellation = True
worker.RunWorkerAsync()
End Sub
Private Sub worker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles worker.DoWork
Dim worker As BackgroundWorker = DirectCast(sender, BackgroundWorker)
DataAcquisition = SqliteReader.GetInstance()
' I probably need
' DataAcquisition.ParseEntireDatabase(graphData, graphComputations, m_debug)
' here... but how do I expose graphdata, graphcomputations and m_debug to this sub?
End Sub
Private Sub worker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles worker.ProgressChanged
dataProgress = CInt(((DataAcquisition.currentRow + 1) / DataAcquisition.totalRows) * 100)
progress.Value = dataProgress
End Sub
RunWorkerAsync has a second version that takes a parameter. You can use that to pass any values (or references) your worker needs.
That said, you shouldn’t be updating form elements from inside the worker. Your worker should fire the ProgressChanged event when you want the UI to update, and you handle it there. That one also has a version that can send a value back. (Or many values if you send back an array, list, or custom class.)
The last step in this is that you need to actually fire ProgressChanged.
DataAcquisition.ParseEntireDatabasemay not do that, in which case using it won’t allow this method to work.