更新进度条WPF Visual studio

时间:2014-06-17 00:06:20

标签: wpf multithreading visual-studio

所以我的问题可能听起来很熟悉,我只想与我的程序中正在处理的数据同时更新进度条。

我有两个窗口:StartupWindow和UpdateWindow。 应用程序首先创建启动窗口,用户将按下按钮以打开UpdateWindow。以下是按钮的代码:

Private Sub btnUpdateClick(sender As Object, e As RoutedEventArgs) Handles btnUpdate.Click
    Dim updateWindow As New UpdateWindow
    updateWindow.ShowDialog()

    btnUpdate.IsEnabled = False
End Sub

使用此代码我得到了大多数其他人所犯的错误:" 调用线程无法访问此对象,因为另一个线程拥有它。"

        Private Sub updateDevice()
             Dim currPercent As Integer 
             currPercent = ((sentPackets / totalPacketsToWrite) * 100)
             progressLabel.content = currPercent.ToString + "%"
             pb.Maximum = totalPacketsToWrite
             pb.Value = sentPackets
                If sentPackets < totalPacketsToWrite Then
                    '....update....
                Else
                    MsgBox("Device now has update stored on flash!")
                    '...close everything up
                End If
        End Sub

以下是我迄今为止尝试过的三件事:

  1. 使用Invoke / Dispatcher / Delegate尝试似乎只能将更新放在不同的线程队列中?似乎暂停其他线程以更新UI ...
  2. 实施BackgroundWorker类并使用它的报告进度,这有效但我只能更新bw.DoWork下的进度条我拨打了很多电话,并且有来自外部设备的响应,因此很难全部放入我的代码在一个函数下。
  3. 我在某处读到,因为这是第二个创建的窗口(从原始窗口调用),我会遇到问题。所以我采取了某人的解决方案,并尝试在“更新”时创建并使用全新的线程。按下了按钮,即:
  4. 需要注意的是,我添加了一个&#39;取消&#39;按钮:

    Private Sub buttonStart_Click(sender As Object, e As RoutedEventArgs) Handles btnStart.Click
                    btnStart.IsEnabled = False
                    btnStart.Visibility = Windows.Visibility.Hidden
                    btnCancel.IsEnabled = True
                    btnCancel.Visibility = Windows.Visibility.Visible
                    beginUpdate()
        End Sub
    
    
    Private Sub buttonCancel_Click(sender As Object, e As RoutedEventArgs) Handles btnCancel.Click
                    btnStart.IsEnabled = True
                    btnStart.Visibility = Windows.Visibility.Visible
                    btnCancel.IsEnabled = False
                    btnCancel.Visibility = Windows.Visibility.Hidden
                    'TODO MAKE IT CANCEL
        End Sub
    

    每次点击更新/取消按钮时,进度条都会更新。每次按下按钮,它都会将进度条刷新到当前完成状态。我很困惑,如果它只是一个窗口,我能够更新用户界面......但是如果用户按下按钮来调用新窗口,我就无法在第二个窗口中更新任何内容。有什么建议吗?

    编辑: 我最终创建了在我的长代码中更新的全局变量。在我做任何其他事情之前,先运行后台工作程序并且它与我的进程异步运行,更新进度条:

    Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
                Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
                While finished = False
                    Threading.Thread.Sleep(50)
                    bw.ReportProgress(currPercent)
                End While
            End Sub
    

    我的代码的开头很简单 - 就像这样:

    Private Sub buttonStart_Click(sender As Object, e As RoutedEventArgs) Handles btnStart.Click
                bw.RunWorkerAsync()
                beginUpdate()
            End Sub
    

1 个答案:

答案 0 :(得分:1)

首先要做的事情......让ProgressBar正常工作:对于本部分,请在Stack Overflow上阅读我对Progress Bar update from Background worker stalling问题的回答。现在,让我们假设您已经获得ProgressBar工作的基本更新...接下来,您希望能够取消该工作。相应地更新DowWork方法是一件简单的事情:

private void DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i <= 100; i++)
    {
        if (IsCancelled) break; // cancellation check
        Thread.Sleep(100); // long running process
        backgroundWorker.ReportProgress(i);
    }
}

因此,您需要做的就是取消长时间运行的流程,ProgressBar更新是将IsCancelled属性设置为true