VB.NET progressbar backgroundworker

tmighty picture tmighty · Nov 3, 2012 · Viewed 29.9k times · Source

When my application starts, and it has just been upgraded, I am doing a local database update (sqlite).

It is like that: The user starts my app, and then I start the upgrade process. During this upgrade process I am showing a form that has a continuous progressbar. This form closes when the upgrade process is done and the user can then start using my application.

But the progressbar won't animate since the upgrade process is so intensive.

In my old VB6 version I used an ActiveX-Exe that has 1 form and shows a progressbar. This was my "background worker".

I am not sure if I can use the same approach in VB.NET.

I have only seen examples that then do the work in the background worker, but I have not seen any examples where the progressbar itself was the background worker.

The database upgrade needs to be blocking, the user may NOT use my application before the database upgrade was done. This means that only the progressbar should "out of process", but not the upgrading.

Thank you very much!

Answer

Jeremy Thompson picture Jeremy Thompson · Nov 21, 2012

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:

enter image description here