当我的应用程序启动时,并且它刚刚升级,我正在执行本地数据库更新(sqlite)。
它是这样的:用户启动我的应用程序,然后我开始升级过程。在这个升级过程中,我显示了一个具有连续进度条的表单。此表单在升级过程完成后关闭,然后用户可以开始使用我的应用程序。
但是进度条不会有动画效果,因为升级过程太密集了。
在我的旧VB6版本中,我使用了一个有1个表单并显示进度条的ActiveX-Exe。这是我的“后台工作人员”。
我不确定是否可以在VB.NET中使用相同的方法。
我只看到过在后台工作者中执行工作的示例,但我没有看到进度条本身是后台工作者的任何示例。
数据库升级需要阻止,在数据库升级完成之前,用户可能不会使用我的应用程序。这意味着只有进度栏应该“进程外”,而不是升级。
非常感谢!
发布于 2012-11-21 13:05:22
先读一下这个:Use of Application.DoEvents()
因此,在读完上面的答案后,你将永远不会再使用DoEvents,而且如果没有DoEvents (和/或使ProgressBar无效,以便它的Paint事件将被激发),“进度条将不会激活,因为升级过程非常密集”。
因此Cthulhu的评论是--“你可以用进度条创建一个对话框,使该对话成为模态对话,然后在后台工作人员上执行你的数据库工具。”是最好的前进方式之一。
我已经翻译了一个我使用的C#实现,你应该可以直接把它放进去。
这是ProgressBar表单:
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 -这将适合您的使用,因为很难预测更新数据库所需的时间:

发布于 2012-11-15 15:06:58
在我看来,从你的要求来看,你正在寻找:
Application.DoAction()我在一个应用程序中经历过,需要从xml加载2000到3000项相关细节,而实现的过程是一个接一个地读取项,这会挂起该过程。在循环中使用上面的代码行解决了我的问题。UI未挂起,用户可以在其他表单上工作。这对我来说似乎是progressbar is now as background process (在某种程度上)。
希望它能帮上忙!
发布于 2012-11-20 08:06:14
我理解您希望将进度栏作为后台线程的愿望,但我相当确定您无法做到这一点。因为您想要更新应用程序的可视组件,所以UI需要是主线程。禁用窗体上的所有控件非常容易,包括菜单项。
让我建议这个过程:
这将给你一个在后台线程中运行的进度条的外观,同时仍然给你的应用程序提供所需的主线程阻塞。
https://stackoverflow.com/questions/13206926
复制相似问题