1

私は、データベースに行き、値を取得し、gridview行ごとに入力するさまざまな値に対して実行されるメソッドを持っています。

各呼び出しには時間がかかり、プロセスが終了するまで画面がフリーズします。gridviewメソッドの実行中、画面をフリーズせずに値を表示するのが好きです。

以下のようなものを試しましたが、それでも画面がフリーズし、プロセスが終了するまでグリッドに値が表示されません。

Application.Doeventsループで使用した場合、グリッドにデータを表示するものは使用したくありません。

どんな助けでもありがたいです

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click

        Dim t = New Threading.Thread(AddressOf MyWork)
        t.Start()
End Sub


Private Sub MyWork()
        If Me.InvokeRequired Then
            Me.Invoke(New MethodInvoker(AddressOf DoWork))
        End If
End Sub

Private Function DoWork() As Boolean

    For i As Integer = 1 To 1000000
        FillGrid(i)
    Next    
End Function
4

1 に答える 1

2

ProgressChangedイベントを持つBackgroundWorkerクラスを使用してみてください。これにより、長時間の操作中にユーザーインターフェイスに中間更新を提供できます。DoWork関数では、ReportProgressを数回呼び出し、任意オブジェクトをProgressChangedイベントに渡してUIを更新できます。

概念を示す簡単な例を次に示します。BackgroundWorkerまず、からデザイナービューのフォームにを追加しToolBoxます。インスタンスは、デザイナーウィンドウの下部に表示されます。を選択し、プロパティBackgroundWorkerをに設定します。WorkerReportsProgressTrue

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    BackgroundWorker1.RunWorkerAsync()
End Sub

Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Dim list1 As New List(Of String)
    list1.Add("A")
    list1.Add("B")
    list1.Add("C")
    BackgroundWorker1.ReportProgress("50", list1)
    Dim list2 As New List(Of String)
    list2.Add("1")
    list2.Add("2")
    list2.Add("3")
    BackgroundWorker1.ReportProgress("100", list2)
End Sub

Private Sub BackgroundWorker1_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    Dim myList As List(Of String)
    myList = e.UserState
    For Each str As String In myList
        DataGridView1.Rows.Add(str)
    Next
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    MessageBox.Show("Operation Complete")
End Sub

これが何が起こっているのかについての説明です。ルーチンでは、UIよりもDoWork長い操作を実行します。separate thread関数を呼び出すときにReportProgress、パーセンテージとオブジェクトの2つのパラメーターを渡すことができます。この場合、2番目のパラメーターの方が重要です。ルーチンではProgressChanged、同じオブジェクトをから取得し、e.UserStateそれを使用して必要な処理を実行します。これはで発生するUI threadため、ここからコントロールを更新できます。このRunWorkerCompletedルーチンは、操作が終了したときに呼び出され、で実行されますUI thread。これから取り除く重要なことは、関数を呼び出すたびにBackgroundWorkerとの間でスレッドセーフなハンドオフが実行されることです。UIReportProgress

于 2013-02-08T13:43:55.130 に答える