VB.NET progressbar backgroundworker
First read this: Use of Application.DoEvents()
So after reading the above answer you will never using DoEvents ever again, and without the DoEvents (and/or Invalidating the ProgressBar so its Paint event will fire) the "progressbar won't animate since the upgrade process is so intensive"
Hence Cthulhu's comment - "You can make a dialog with a progressbar, make that dialog modal and execute your db-stuff on a backgroundworker." is one of the best ways forward.
I have translated a C# implementation of this that I use, you should be able to drop it straight in.
This is the ProgressBar Form:
Public Partial Class ThinkingProgressBar
Inherits Form
Private startTime As System.DateTime = DateTime.Now
Public Sub New()
InitializeComponent()
End Sub
Private Sub lblClose_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs)
Me.Tag = "Cancelled"
Me.Hide()
End Sub
Public Sub SetThinkingBar(ByVal switchedOn As Boolean)
If switchedOn Then
lblTime.Text = "0:00:00"
startTime = DateTime.Now
Timer1.Enabled = True
Timer1.Start()
Else
Timer1.Enabled = False
Timer1.Stop()
End If
End Sub
Private Sub timer1_Tick(sender As Object, e As EventArgs)
Dim diff As New TimeSpan()
diff = DateTime.Now.Subtract(startTime)
lblTime.Text = diff.Hours & ":" & diff.Minutes.ToString("00") & ":" & diff.Seconds.ToString("00")
lblTime.Invalidate()
End Sub
End Class
Drag/Drop a BackgroundWorker control onto the form, here are the background worker events:
Private Sub backgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
e.Result = e.Argument
'DirectCast(e.Result, ThinkingProgressBar).SetThinkingBar(True)
'DO LONG OPERATION HERE
End Sub
Private Sub backgroundWorker1_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Dim dlg As ThinkingProgressBar = TryCast(e.Result, ThinkingProgressBar)
If IsNothing(dlg) = False Then
dlg.SetThinkingBar(False)
dlg.Close()
End If
End Sub
And here is the calling code for when your application starts and does the upgrading:
Dim dlg As New ThinkingProgressBar()
dlg.SetThinkingBar(True)
BackgroundWorker1.RunWorkerAsync(dlg)
dlg.ShowDialog()
If IsNothing(dlg.Tag) = False AndAlso dlg.Tag.ToString() = "Cancelled" Then
Return
End If
A couple of things, you may prevent the user from Cancelling (ie lblClose_LinkClicked
) and put in protective/defensive programming to handle cases where the user kills the process or turns off their PC during the upgrade.
And the ProgressBar is actually an animated gif - and this will suit your usage because estimating the time it takes to update a database is very hard to predict:
From your requirements it seems to me that you are looking for:
Application.DoAction()
I have experienced in an application that there was a need to load 2000 to 3000 items related detail from xml and the implemented process was reading items one by one which hangs up the process. Using the above line in the loop resolved my issue. The UI did not hang-up and user was able to work on other forms. This appeared progressbar is now as background process
(upto some extent) to me.
Hope it helps!
I understand your desire to make the progressbar the background thread, but I am fairly certain that you will not be able to do this. Because you want to update the visual components of your application, the UI needs to be the primary thread. It is easy enough to disable all of the controls on a form, including menu items.
Let me suggest this process:
Show your form with the progressbar mentioned.
If you show any other forms, disable all child controls that are directly on the form. Depending on the control, you may have to walk through its child controls to disable them.
In the code that performs the database update, update the progressbar's value to what ever value you desire. Upon updating the value, call the progressbar's refresh method. This will force the progressbar to paint correctly.
Once your update completes, hide the progressbar, re-enable all of the controls on all of the forms that you disabled.
This will give you the appearance of a progressbar that is running in the background thread while still giving your application the blocking of the main thread as desired.