VB.NET progressbar backgroundworker

后端 未结 6 2116
梦如初夏
梦如初夏 2020-11-28 13:49

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 th

6条回答
  •  时光取名叫无心
    2020-11-28 14:33

    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

提交回复
热议问题