在长时间运行的过程中填充gridview(刷新)

时间:2013-02-08 09:36:12

标签: .net vb.net winforms multithreading .net-4.0

我有一个针对不同值运行的方法,该方法会转到数据库,检索值并逐行填充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

1 个答案:

答案 0 :(得分:2)

您可以尝试使用BackgroundWorker类,该类具有ProgressChanged事件,允许您在长时间操作期间为用户界面提供中间更新。在DoWork函数中,您可以多次调用ReportProgress并将任何对象传递给ProgressChanged事件以更新UI。

这是一个展示概念的简单示例。首先在BackgroundWorker的设计器视图中向表单添加ToolBox。该实例将显示在设计器窗口的底部。选择BackgroundWorker并将WorkerReportsProgress属性设置为True

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

以下是对正在发生的事情的解释。在DoWork例程中,您将在separate thread而不是UI上执行长时间操作。当你调用ReportProgress函数时,你可以传递两个参数:百分比和一个对象......在这种情况下,第二个参数更重要。在ProgressChanged例程中,您将从e.UserState获取相同的对象并使用它执行您想要的操作。这发生在UI thread上,因此您可以从此处更新控件。操作完成后调用RunWorkerCompleted例程,并在UI thread上运行。重要的是,只要您调用BackgroundWorker函数,就会在UIReportProgress之间执行线程安全切换。