我制作了一个同时运行三个后台工作程序的应用程序。它基本上更新了它正在执行的三个数据网格视图。我的问题是,如果我按下最大化框按钮或任何 datagridview 中的任何位置,程序会挂起很长时间。我可以使用水平滚动,但不能使用垂直滚动。我已经尝试过 Backgroundworker_runworkercompleted 并在线程更新了各自的数据网格视图后根据需要触发。这是正常行为还是我做错了什么任何建议都会有所帮助。PS:我已经使用 step 方法运行了整个程序,并且它们在代码中没有无限循环。提前感谢约翰
6 回答
Backgroundworker1.RunWorkerAsync()
在调用临时禁用 datagridview 滚动条之前放置这行代码。
DataGridView1.ScrollBars = ScrollBars.None
BackgroundWorker1_RunWorkerCompleted
现在通过在事件中添加这行代码来重新启用 datagridview 的滚动条。
DataGridView1.ScrollBars = ScrollBars.Both
这永远不会使您的应用程序无响应。
好的,我已经找到了解决问题的方法,在逐步消除感知到的问题点的同时,我在 backgroundworker.dowork 事件之外调用了我的 datagridview,瞧,这解决了问题。故事的寓意“永远不要从背景工作线程内更新数据网格视图”,特别是当您不知道自己做错了什么时:)。我希望它将来对某人有所帮助。
听起来您仍在以某种方式阻塞 UI 线程。发布一些代码片段可能对您有所帮助。另外,您的进程的 CPU 利用率是多少?如果 CPU 使用率很高,您可能会以某种方式使 UI 线程处于饥饿状态。
现在回答@Jhon 为时已晚,但似乎它可能对其他人有所帮助。就我而言,我使用的是 BindingSource 并且 UI 仅在必须出现滚动条的记录太多时才会冻结。
当您使用后台工作者、任务或线程来完成工作时,您必须在主 UI 线程上更新您的 UI 控件。为此,您可以调用相应线程中的方法。
一个简单的例子:
myDataGridView.Invoke((MethodInvoker)delegate { myBindingSource.DataSource = myData; });
但我更喜欢这个解决方案: InvokeIfRequired
我有同样的问题。当我的 dataGridViews 从 UI 线程更新时,它们运行良好。当我尝试从 backgroundWorker 向它们添加一系列行时,它们变得没有响应。
为了纠正这个问题,我将行添加到数据表中。当我启动 backgroundWorker 时,我将 dataGridView 的 .datasource 属性设置为空。工人完成后,我再次将其设置回数据表。这既迫使 dataGridView 自我更新,又切断了工作线程中发生的事情与 UI 中显示的内容之间的同步连接,这似乎减轻了工作人员完成时的无响应。
示例用法:
Private Sub button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn1.Click
If bgWorker1.IsBusy <> True Then
dataGridView1.DataSource = Nothing
bgWorker1.RunWorkerAsync()
End If
End Sub
Private Sub bgWorker_DoWork(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bgWorker1.DoWork
dataTable1.Rows.Add("data")
End Sub
Private Sub bgWorker_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As RunWorkerCompletedEventArgs) Handles bgWorker1.RunWorkerCompleted
dataGridView1.DataSource = dataTable1
dataGridView1.Refresh()
End Sub
您必须确保从 UI 线程更新 datagridviews。