progressbar.performstep()函数如何工作



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

预先感谢!

我认为您看到的(或看不到)是进度栏需要有限的时间来促进每个步骤的事实。

当您在UI线程上调用Threading.Thread.Sleep时,这会阻止进度栏重新绘制到Sleep

之后

您应该做的是更新背景工人的进度栏,然后我想您会看到自己想要的效果。

在您的表格中添加一个背景工作者

更改按钮单击代码以启动工人:

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

问题是您调用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

感谢马特·威尔科(Matt Wilko)给我的线索。这是我的代码。

从工具箱的"组件"选项卡中,添加一个名为backgroundWorker2BackgroundWorker组件。为BackgroundWorker创建DoWorkProgressChanged事件处理程序。

以下代码将启动组件。

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

有关BackgroundWorker的更多信息:http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v = vs.110).aspx

最新更新