ПрогрессБар Горе. Получение потока пользовательского интерфейса для обновления при чтении базы данных - PullRequest
0 голосов
/ 08 августа 2011

У меня проблемы с обновлением индикатора выполнения. Я был бы в порядке только с движущимся шатром. По сути, я читаю подпрограмму базы данных в классе SqliteReader.vb. Я новичок в Visual Basic, и я уверен, что мне нужно использовать подпрограмму worker_DoWork, но я не уверен, как представить мои переменные, поступающие из Form1: graphData, graphComputations, m_debug для подпрограммы worker_DoWork. Как это обычно делается?

Public Class SqliteReader
   Public Sub ReadDataBase
     End Sub
End Class

Это обновление графика (элемента zedgraph) в главной форме, Form1.vb. Я вызываю прогрессбар из основной формы так:

    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 ]

2 голосов
/ 08 августа 2011

RunWorkerAsync имеет вторую версию, которая принимает параметр. Вы можете использовать его для передачи любых значений (или ссылок), необходимых вашему работнику.

Тем не менее, вы не должны обновлять элементы формы изнутри рабочего. Ваш работник должен запустить событие ProgressChanged, когда вы хотите, чтобы пользовательский интерфейс обновился, и вы обрабатываете его там. У этой версии также есть версия, которая может отправить значение обратно. (Или много значений, если вы отправляете обратно массив, список или пользовательский класс.)

Последний шаг в том, что вам нужно запустить ProgressChanged. DataAcquisition.ParseEntireDatabase может этого не делать, и в этом случае его использование не позволит этому методу работать.

0 голосов
/ 06 марта 2012

Для Рапунзо, выше .. Мое окончательное решение было таким:

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()

Надеюсь, это поможет.

0 голосов
/ 08 августа 2011

Если graphData, graphComputations, m_debug уже является членом ProgressBar, а worker_DoWork является членом ProgressBar, то вам больше нечего делать. Вы должны иметь доступ к ним напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...