ProgressBar.PerformStep()函数如何工作?

时间:2014-03-10 08:22:30

标签: vb.net progress-bar

我对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?

提前致谢!

3 个答案:

答案 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创建DoWorkProgressChanged个事件处理程序。

以下代码将启动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