使用后台工作人员更新 datagridviews 后 GUI 冻结

发布于 2024-08-24 12:04:26 字数 256 浏览 8 评论 0原文

我制作了一个同时运行三个后台工作者的应用程序。它基本上更新了三个数据网格视图,这是它正在做的事情。我的问题是,如果我按最大化框按钮或任何数据网格视图中的任何位置,程序都会挂起相当长的时间。我可以使用水平滚动,但不能使用垂直滚动。我尝试过Backgroundworker_runworkercompleted,它在线程更新各自的datagridviews后根据需要触发。这是正常行为还是我做错了什么任何建议都会有帮助。 PS:我已经使用步骤方法运行了整个程序,并且代码中没有无限循环。 提前致谢 约翰

I have made an application which runs three backgroundworkers simultaneously. It basically updates three datagridviews, which it is doing spot on. My problem is if I press maximizebox button or anywhere in any of the datagridview the program hangs for quite a long time. I am able to use the horizontal scroll but not vertical scrolls. I have tried Backgroundworker_runworkercompleted and it fires as required after threads have updated their respective datagridviews. Is it a normal behaviour or am i doing something wrong any suggestions would be helpful.
P.S: I have run the whole program using step method and their is no infinite loop in the code.
Thanks in advance
Jhon

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

初吻给了烟 2024-08-31 12:04:26

将此行代码放在调用 Backgroundworker1.RunWorkerAsync() 之前,以暂时禁用 datagridview 滚动条。

DataGridView1.ScrollBars = ScrollBars.None

现在,通过在 BackgroundWorker1_RunWorkerCompleted 事件中添加这行代码来重新启用 datagridview 的滚动条。

DataGridView1.ScrollBars = ScrollBars.Both

这永远不会使您的应用程序无响应。

Place this line of code just before when you are calling Backgroundworker1.RunWorkerAsync() to temporarily disable your datagridview scroll bars.

DataGridView1.ScrollBars = ScrollBars.None

Now Re-enable scroll bars of your datagridview by adding this line of code in BackgroundWorker1_RunWorkerCompleted event.

DataGridView1.ScrollBars = ScrollBars.Both

This will never make your application unresponding.

ゞ记忆︶ㄣ 2024-08-31 12:04:26

听起来你仍然以某种方式阻塞 UI 线程。发布一些代码片段可能会对您有所帮助。另外,您的进程的 CPU 利用率是多少?如果 cpu 使用率很高,则可能会导致 UI 线程处于饥饿状态。

It sounds like you are still blocking the UI thread somehow. It may be helpful for you to post some code snippets. Also, what is the CPU utilization of your process? If the cpu usage is high, you may be starving the UI thread somehow.

¢蛋碎的人ぎ生 2024-08-31 12:04:26

好吧,我已经找到了问题的解决方案,在按顺序消除发现的问题点的同时,我在 backgroundworker.dowork 事件之外调用了我的 datagridview ,瞧,解决了问题。
这个故事的寓意是“永远不要从后台工作线程内更新数据网格视图”,特别是当您不知道自己做错了什么时:)。我希望它能帮助将来的人。

Okay I have found the solution to my problem, while working out sequential elimination of the perceived trouble spots, I called my datagridview outside of the backgroundworker.dowork event and voila that solved the problem.
Moral of the story "NEVER UPDATE A DATA GRID VIEW FROM WITHIN THE BACKGROUNDWORKER THREAD" specially when you don't know what are you doing wrong :). I hope it will help someone in future.

旧伤还要旧人安 2024-08-31 12:04:26

您必须确保从 UI 线程更新 datagridviews。

You have to make sure that you are updating the datagridviews from the UI thread.

万劫不复 2024-08-31 12:04:26

我也有同样的问题。当我的 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

I had the same problem. When my dataGridViews were being updated from the UI thread, they worked fine. When I tried to add a series of rows to them from the backgroundWorker, they became unresponsive.

To correct this, I added the rows to a dataTable instead. When I kick off the backgroundWorker, I set the .datasource property of the dataGridView to nothing. When the worker completes, I set it back to the dataTable again. This both forces the dataGridView to update itself, and severs the synchronous connection between what it happening in the worker thread, and what is being displayed in the UI, which seems to alleviate the unresponsiveness when the worker completes.

Sample usage:

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
不离久伴 2024-08-31 12:04:26

现在回答@Jhon 已经太晚了,但它似乎可能对其他人有帮助。
就我而言,我使用的是 BindingSource,并且只有在必须出现滚动条的记录太多时,UI 才会冻结。

当您使用后台工作程序、任务或线程来完成工作时,您必须更新主 UI 线程上的 UI 控件。
为此,您可以调用相应线程中的方法。

一个简单的例子:

myDataGridView.Invoke((MethodInvoker)delegate { myBindingSource.DataSource = myData; });

但我更喜欢这个解决方案:
InvokeIfRequired

It's too late to answer to @Jhon but it seems like it might help other people.
In my case, I was using a BindingSource and the UI only froze if there where so many records that scrollbars had to appear.

When you use a background worker, task or thread to do the work, you have to update your UI controls on the main UI thread.
To do that you can Invoke a method in the corresponding thread.

A simple example:

myDataGridView.Invoke((MethodInvoker)delegate { myBindingSource.DataSource = myData; });

But i prefer this solution:
InvokeIfRequired

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文