ProgressBar遇到麻烦。在读取数据库时获取UI线程进行更新

时间:2011-08-08 17:54:09

标签: vb.net progress-bar

我无法获得进度条进行更新。我只需要一个移动的选框吧。基本上,我正在读取SqliteReader.vb类中的数据库例程。我是visual basic的新手,我确定我需要使用worker_DoWork例程,但我不确定如何将来自Form1:graphData,graphComputations,m_debug的变量暴露给worker_DoWork子。这通常是怎么做的?

Public Class SqliteReader
   Public Sub ReadDataBase
     End Sub
End Class

这是更新主窗体Form1.vb上的图形(zedgraph元素)。我从主窗体中调用了进度条,如下所示:

    ProgressBar.Initialize(channelArray, computationArray, m_debug)        

下面的ProgressBar.vb:

Partial Public Class ProgressBar
    Dim DataAcquisition As New SqliteReader
    Dim WithEvents worker As New BackgroundWorker

Public Sub Initialize(ByRef graphData As Channels(), ByRef graphComputations As Computations(), ByVal m_debug As Integer)
    DataAcquisition = SqliteReader.GetInstance()
    Me.Show()
    Me.Update()
    Dim Update_Thread As Thread(AddressOf Update_ThreadExecute)

    Update_Thread.Priority = ThreadPriority.Normal
    Update_Thread.Start()
    DataAcquisition.ParseEntireDatabase(graphData, graphComputations, m_debug)
    Me.Close()
End Sub


Private Sub ProgressBarStart(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      DataAcquisition = SqliteReader.GetInstance()
      progress.Style = ProgressBarStyle.Marquee
      worker.WorkerReportsProgress = True
      worker.WorkerSupportsCancellation = True
      worker.RunWorkerAsync()
  End Sub

  Private Sub worker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles worker.DoWork
         Dim worker As BackgroundWorker = DirectCast(sender, BackgroundWorker)
         DataAcquisition = SqliteReader.GetInstance()
         ' I probably need 
         ' DataAcquisition.ParseEntireDatabase(graphData, graphComputations, m_debug)
         ' here... but how do I expose graphdata, graphcomputations and m_debug to this sub?
         End Sub

  Private Sub worker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles worker.ProgressChanged
      dataProgress = CInt(((DataAcquisition.currentRow + 1) / DataAcquisition.totalRows) * 100)
      progress.Value = dataProgress
  End Sub

3 个答案:

答案 0 :(得分:2)

RunWorkerAsync has a second version that takes a parameter.您可以使用它传递您的工作人员需要的任何值(或引用)。

也就是说,您不应该从工作者内部更新表单元素。当您希望UI更新时,您的工作人员应该触发ProgressChanged事件,并在那里处理它。 That one also has a version that can send a value back.(如果发送回数组,列表或自定义类,则为多个值。)

最后一步是你需要实际触发ProgressChanged。 DataAcquisition.ParseEntireDatabase可能不会这样做,在这种情况下,使用它不会允许此方法起作用。

答案 1 :(得分:0)

如果graphData, graphComputations, m_debug已经是ProgressBar的成员且worker_DoWork是[{1}}的成员,则您无需再做任何事情。您应该可以直接访问它们。

答案 2 :(得分:0)

对于Rapunzo,上面..我的最终解决方案是:

Partial Public Class ProgressBar
Dim _mDataAcquisition As New SqliteReader
Public Property DataProgress As Integer = 0
Dim WithEvents _mProgressWorker As New BackgroundWorker
Public Sub Initialize(ByRef graphData As List(Of Channels), ByRef auxData As List(Of Channels), _
                      ByRef graphComputations As List(Of Computations))
    _mDataAcquisition = SqliteReader.GetInstance()
    Show()
    Update()
    _mDataAcquisition.ParseEntireDatabase(graphData, auxData, graphComputations)
    Close()
End Sub
Private Sub ProgressBarStart(ByVal sender As System.Object, ByVal e As EventArgs) Handles MyBase.Load
    progress.Style = ProgressBarStyle.Blocks
    _mProgressWorker.WorkerReportsProgress = True
    _mProgressWorker.WorkerSupportsCancellation = True
    _mProgressWorker.RunWorkerAsync()
    progress.Visible = True
    progress.Maximum = 100
    progress.Value = 0
End Sub
Public Sub WorkerProgressChanged()
    progress.Value = DataProgress
    Invalidate()
End Sub
Private Sub WorkerRunWorkerCompleted(ByVal sender As Object, _
                                     ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
                                     Handles _mProgressWorker.RunWorkerCompleted
    progress.Visible = False
    progress.Value = 0
    Close()
End Sub

从那里,只需调用ProgressBar.Initialize启动它

更新:

    ProgressBar.DataProgress = CInt((currentIt / totalIt) * 100)
    ProgressBar.WorkerProgressChanged()

并结束:

    ProgressBar.DataProgress = 100
    ProgressBar.WorkerProgressChanged()

希望这有帮助。