首先阅读此内容:Application.DoEvents() 的使用
因此,在阅读上述答案后,您将永远不会再使用 DoEvents,并且没有 DoEvents(和/或使 ProgressBar 无效,因此其 Paint 事件将触发)“progressbar 不会动画,因为升级过程非常密集”
因此 Cthulhu 的评论 - “您可以使用进度条创建对话框,使该对话框成为模态并在后台工作人员上执行您的 db-stuff。” 是最好的前进方式之一。
我已经翻译了我使用的 C# 实现,你应该可以直接把它放进去。
这是进度条表单:
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
将 BackgroundWorker 控件拖放到窗体上,这里是后台工作者事件:
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
这是您的应用程序启动和升级时的调用代码:
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
有几件事,您可以阻止用户取消(即lblClose_LinkClicked
)并进行保护/防御性编程以处理用户在升级期间终止进程或关闭其 PC 的情况。
ProgressBar 实际上是一个动画 gif - 这将适合您的使用,因为估计更新数据库所需的时间很难预测: