【问题标题】:How to implement fast updating table in windows forms?如何在 windows 窗体中实现快速更新表格?
【发布时间】:2014-11-20 02:41:42
【问题描述】:

我目前正在使用DataGridView 以表格格式显示我的数据。它有 5 列。

Problem: 我收到的数据速度非常快,比如 5 毫秒。我正在使用BlockingCollection 从一个线程将数据存储在其中,并通过从另一个线程中获取数据来更新表。发生的情况是队列的大小不断增加,因为数据进入的速度非常快。

当我停止发送数据时,DataGridView 会继续添加行,理想情况下应该在我停止发送数据时立即停止。

我尝试实现一个线程安全的循环队列,但没有成功,我错过了很多来自它的消息。

我可以使用任何其他控件来代替非常快的DataGridView 吗?

或者如果有人可以告诉我如何更好地实现它?

【问题讨论】:

  • 您是在添加下一个块之前追加行还是清除整个网格?
  • 您是否将新项目一一添加到 datagridview 中?最好做一些兑现,并按包添加数据到网格(例如100行)......
  • 您提到您“通过获取数据来更新表”,因此如果“数据进入的速度非常快”,请放慢获取的节奏数据。
  • 对 DataGridView 也使用 DoubleBuffering
  • 谢谢。 c# 中是否有任何内置的线程安全循环队列,例如用于线性线程安全数据结构的 BlockingCollection?

标签: c# multithreading winforms datagridview


【解决方案1】:

您的限制因素很可能是更新DataGridView,而创建更快的队列对您没有帮助。例如,您的描述表明您的更新循环如下所示:

while (queue not empty)
{
    get queue item
    update data grid
}

每次更新数据网格时,都会运行一些布局逻辑,并且很可能会尝试更新屏幕。这是一个非常昂贵的操作。如果DataGridView 必须在每次插入后更新屏幕,几乎可以肯定DataGridView 无法跟上每秒 200 条记录的插入速度。

我建议的第一件事是批量更新DataGridView,在开始批处理之前调用SuspendLayout,在批处理结束时调用ResumeLayout。所以你的循环变成了这样:

int MaxItemsPerBatch = 10;

while (queue not empty)
{
    grid.SuspendLayout();
    int numItems = MaxItemsPerBatch;
    while (numItems > 0 && queue not empty)
    {
        get item from queue
        update data grid
        numItems = numItems - 1
    }
    grid.ResumeLayout();
}

在这里,布局逻辑每批只运行一次,所以你应该快 10 倍。这仍然为您提供每秒 20 次更新的屏幕更新率,这将比您的用户看到的更快。您可以将批量大小增加到 100,而不会受到用户的任何反对。

【讨论】:

  • 感谢您的建议。它提高了表更新速度。我仍然错过了很多消息,我想那是因为我正在使用我的循环队列实现。您能否与我分享线程安全循环队列的最佳代码?
  • @ankur:我的建议是使用BlockingCollection。我确信BlockingCollection 可以轻松处理每秒超过 200 条记录的入队和出队。它不是“最优化的”,但速度非常快并且效果很好。我怀疑您的限制因素仍然是DataGridView UI 更新。您是否尝试增加批量大小?
  • 是的,先生,您没看错,我遇到了DataGridView 的问题。截至目前,我正在使用普通的Queue 并暂停布局,直到表格中发生滚动事件。它改进了一些 UI,但我需要做得更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多