我对VB.net中的进度条感到困惑,这是我的代码
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ProgressBar_my.Minimum = 0
ProgressBar_my.Maximum = 10
ProgressBar_my.Step = 1
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ProgressBar_my.PerformStep()
Threading.Thread.Sleep(5000)
If 1 = 1 Then
ProgressBar_my.PerformStep()
ProgressBar_my.PerformStep()
End If
'Threading.Thread.Sleep(2000)
End Sub
对于上面的代码,我预期的是,点击Button1
后,进度条会将进度状态增加1,然后暂停5 sec
,然后会增加进度状态为2。
但是,在我运行上述代码之后,我看到的是,点击Button1
后,进度条会在5 sec
之后不断增加3。
有人可以告诉我为什么它的行为如此,我应该如何编程我的代码以便我可以增加1,然后暂停5秒再增加2?
提前致谢!
答案 0 :(得分:1)
我认为你所看到的(或未看到的)是进度条花费有限的时间来推进每一步。
当你在UI线程上调用Threading.Thread.Sleep
时,这会阻止进度条重绘,直到Sleep
你应该做的是更新后台工作人员的进度条,然后我想你会看到你想要的效果。
将BackgroundWorker添加到表单
更改按钮点击代码以启动工作人员:
Private Sub frmSO_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ProgressBar_my.Minimum = 0
ProgressBar_my.Maximum = 10
ProgressBar_my.Step = 1
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync
End Sub
然后在DoWork事件中执行更新:
'define a delegate to handle updates to the UI thread
Private Delegate Sub PerformStepCallback()
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim cb As PerformStepCallback = AddressOf ProgressBar_my.PerformStep
Me.BeginInvoke(cb)
Threading.Thread.Sleep(5000)
Me.BeginInvoke(cb)
Me.BeginInvoke(cb)
End Sub
答案 1 :(得分:0)
问题是你调用Threading.Thread.Sleep(5000)
,这将暂停当前线程。但这也意味着窗口不会被重绘,所以只有在线程不再暂停后才能看到第一次调用PerformStep
的效果。
您可以使用另一个线程进行等待和第二次更新;在这种情况下最简单的方法是使用任务并行库:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ProgressBar1.PerformStep()
Task.Delay(5000).ContinueWith(Sub()
ProgressBar1.PerformStep()
ProgressBar1.PerformStep()
End Sub, TaskScheduler.FromCurrentSynchronizationContext)
End Sub
答案 2 :(得分:0)
感谢Matt Wilko给我的线索。这是我的代码。
从“工具箱”的“组件”标签中,添加名为BackgroundWorker
的{{1}}组件。为backgroundWorker2
创建DoWork
和ProgressChanged
个事件处理程序。
以下代码将启动Component。
BackgroundWorker
单击按钮并且后台工作程序未运行时调用Public Sub New()
InitializeComponent()
BackgroundWorker2.WorkerReportsProgress = True
BackgroundWorker2.WorkerSupportsCancellation = True
End Sub
。
RunWorkerAsync
每次调用Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If BackgroundWorker2.IsBusy <> True And ProgressBar_my.Value < 6 Then
BackgroundWorker2.RunWorkerAsync()
End If
End Sub
Private Sub BackgroundWorker2_DoWork_1(ByVal sender As System.Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs) _
Handles BackgroundWorker2.DoWork
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
worker.ReportProgress(1)
System.Threading.Thread.Sleep(2000)
worker.ReportProgress(1)
worker.ReportProgress(1)
End Sub
方法时都会引发以下事件。
ReportProgress
有关Private Sub backgroundWorker2_ProgressChanged(ByVal sender As System.Object, _
ByVal e As System.ComponentModel.ProgressChangedEventArgs) _
Handles BackgroundWorker2.ProgressChanged
ProgressBar_my.PerformStep()
End Sub
的更多信息:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx