我有一个针对不同值运行的方法,该方法会转到数据库,检索值并逐行填充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
答案 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
函数,就会在UI
和ReportProgress
之间执行线程安全切换。