Vb Net Update Progress Bar Backgroundworker Threadflip
September 24th, 2007 The.NET Framework 2.0 BackgroundWorker class makes it easy to code simple threading into your applications. However, a common question that gets asked in VB related forums is, “How do I update a control, or controls, from the worker thread?”. Many people seem to be in search of a simple explanation of how to do this. In this article we’ll create a quick and easy example program that will walk you through the steps. Getting Started First, we will need to create a new Windows application.
To execute a time-consuming operation in the background, create a BackgroundWorker and. BackgroundWorker worker. Visual Basic) members of this type are thread.
On our form we’ll add two buttons, btnStart and btnCancel, a progress bar, prgThread, and a listbox, lstValues. You may also want to import System.ComponentModel into the project namespace or onto the form or you can just spell it out like I’m doing below. Next we’re going to add code. Anno 2070 Cheat Engine Hack.
First, we declare the BackgroundWorker object, TestWorker. Note that we’re declaring it with events so that the event structure is built automatically. ' Private WithEvents TestWorker As System.ComponentModel.BackgroundWorker ' ' Now, code is added for the start button, btnStart. Private Sub btnStart_Click( ByVal sender As System. Object, ByVal e As System.EventArgs) Handles btnStart.Click btnStart.Enabled = False btnCancel.Enabled = True lstValues.Items.Clear() prgThread.Value = 0 TestWorker = New System.ComponentModel.BackgroundWorker TestWorker.WorkerReportsProgress = True TestWorker.WorkerSupportsCancellation = True TestWorker.RunWorkerAsync() End Sub First, we disable the start button and enable the cancel button. Next we reset the values for our listbox and and progressbar. Now we’re ready to create our BackgroundWorker object.
Notice that we tell it that we want to have it report progress and support cancellation. Finally, we tell it to run the worker. The Worker Here’s the code for our worker thread. This code is contained in the DoWork event. All it’s doing is looping 100 times and reporting the progress and sleeping 100ms between iterations. We also check for a cancellation state.
Private Sub TestWorker_DoWork( ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles TestWorker.DoWork Dim ListText As String For Value As Integer = 0 To 100 If TestWorker.CancellationPending Then Exit For End If ListText = String.Concat( 'Item #', Value) TestWorker.ReportProgress(Value, ListText) Threading.Thread.Sleep(100) Next End Sub You can also see that in the ReportProgress function call that we’re passing in the current value and a string. Updating Form Controls In the ProgressChanged event, we get to process our values from our DoWork method. Here’s the code: Private Sub TestWorker_ProgressChanged( ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles TestWorker.ProgressChanged prgThread.Value = e.ProgressPercentage lstValues.Items.Add(e.UserState) End Sub ' In this routine, the progress bar and the listbox are updated with values from the worker thread.
Remember that the UserState value is an object and will require conversion if you can’t use an object type. Canceling the Worker Now, what if you want to cancel the worker? Here’s the code that goes into our cancel button’s Click event: Private Sub btnCancel_Click( ByVal sender As System. Object, ByVal e As System.EventArgs) Handles btnCancel.Click TestWorker.CancelAsync() End Sub ' ' Here we call the CancelAsync method.
However, this only sets a flag and, as shown above, our DoWork method has to check for a CancellationPending state. Otherwise, the work will continue until the DoWork routine is exited.
Finishing Things Up When the work has been completed or canceled, the RunWorkerCompleted method is called. In our program, this allows us to reset our buttons. Private Sub TestWorker_RunWorkerCompleted( ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles TestWorker.RunWorkerCompleted btnStart.Enabled = True btnCancel.Enabled = False End Sub That’s how it’s done in a nutshell. Of course, handling multi-threading in your applications can become very tricky. It is recommended that you further review how to avoid problems with threading before implementing it. Let me know if you have any questions about BackgroundWorker or if you have any suggestions or thoughts about this example by leaving me a comment.
Here is a cut down example of how to do Asychrounous Work with VB.Net 4.0. Lets imagine you have a form that has the following imports, Imports System.Windows.Forms Imports System.Threading Imports System.Threading.Tasks That form has two controls Private WithEvents DoSomthing As Button Private WithEvents Progress As ProgressBar Somewhere in your application we have a Function called ExecuteSlowStuff, this function is the equivalent of your executeMyQuery. The important part is the Action parameter which the function uses to show it is making progress. Private Shared Function ExecuteSlowStuff(ByVal progress As Action) As Integer Dim result = 0 For i = 0 To 10000 result += i Thread.Sleep(500) progress() Next Return result End Function Lets say this work is started by the click of the DoSomething Button. Private Sub Start() Handled DoSomething.Click Dim slowStuff = Task(Of Integer).Factory.StartNew( Function() ExceuteSlowStuff(AddressOf Me.ShowProgress)) End Sub You're probably wondering where ShowProgress comes from, that is the messier bit. Private Sub ShowProgress() If Me.Progress.InvokeRequired Then Dim cross As new Action(AddressOf Me.ShowProgress) Me.Invoke(cross) Else If Me.Progress.Value = Me.Progress.Maximum Then Me.Progress.Value = Me.Progress.Minimum Else Me.Progress.Increment(1) End If Me.Progress.Refresh() End if End Sub Note that because ShowProgress can be invoked from another thread, it checks for cross thread calls. In that case it invokes itself on the main thread.
During the query execution you cannot show a real progress bar. MySQL do not deliver any estimation how long the query will take to be finsihed.
You can estimate the time by measuring your old runs and 'fake' the progress bar with this informations. But this is kind of overkill. In most cases it is enough to show the user 'something'.
Like a wheel spinning or a progress bar filling up every 2-3 seconds. If you want a progress bar while filling the items, this is possible without changing much. Just add a progress bar control and increment it inside your 'While(myReader.Reader())' loop.
I even suspect this takes the longer time then the query. If you query takes long, check if you have an index on column! If you want to show the user that something is happening you can use a thread..NET has a nice BackgroundWorker().