1

グリッドビューの合計行数に基づいて、バックグラウンドワーカーのプログレスバーの値をどのように動的にカウントしますか?

4

1 に答える 1

3

BackgroundWorkerは、UIスレッドとは異なるスレッドで実行されます。したがって、バックグラウンドワーカーのDoWorkイベントハンドラーメソッド内からフォームのコントロールを変更しようとすると、例外が発生します。

フォームのコントロールを更新するには、次の2つのオプションがあります。

Imports System.ComponentModel

Public Class Form1
    Public Sub bgw_DoWork(sender As Object, e As DoWorkEventArgs) Handles bgw.DoWork
        ' This is not the UI thread.
        ' Trying to update controls here *will* throw an exception!!
        Dim wkr = DirectCast(sender, BackgroundWorker)

        For i As Integer = 0 To gv.Rows.Count - 1
            ' Do something lengthy
            System.Threading.Thread.Sleep(100)
            ' Report the current progress
            wkr.ReportProgress(CInt((i/gv.Rows.Count)*100))
        Next
    End Sub

    Private Sub bgw_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles bgw.ProgressChanged
        'everything done in this event handler is on the UI thread so it is thread safe

        ' Use the e.ProgressPercentage to get the progress that was reported
        prg.Value = e.ProgressPercentage
    End Sub
End Class
  • デリゲートを呼び出して、UIスレッドの更新を実行します。
Imports System.ComponentModel

Public Class Form1
    Public Sub bgw_DoWork(sender As Object, e As DoWorkEventArgs) Handles bgw.DoWork
        ' This is not the UI thread.
        ' You *must* invoke a delegate in order to update the UI.
        Dim wkr = DirectCast(sender, BackgroundWorker)

        For i As Integer = 0 To gv.Rows.Count - 1
            ' Do something lengthy
            System.Threading.Thread.Sleep(100)
            ' Use an anonymous delegate to set the progress value
            prg.Invoke(Sub() prg.Value = CInt((i/gv.Rows.Count)*100))
        Next
    End Sub
End Class



注意:より詳細な例については、関連する質問に対する私の回答もご覧ください。

于 2012-10-15T13:45:05.247 に答える