非常频繁地更新datagridview [英] update datagridview very frequently

查看:129
本文介绍了非常频繁地更新datagridview的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在合理的时间内用C#刷新DataGridView时遇到麻烦(我是btw的新手,我习惯于Java ...)。

I'm having trouble refreshing my DataGridView in a reasonable time in C# (which I am new to btw, I'm used to java...).

我正在通过每秒20个数据包发送的网络获取数据。我想解析数据并将其放入DataGridView中。我还想将DataGridView的更新间隔从0.1秒调整为1分钟。

I'm getting data over a network with 20 packages sent per second. I'd like to parse the data and put it in a DataGridView. I would also like to adjust the interval in which the DataGridView is updated, from 0.1 seconds to 1 minute.

所以我创建了一个额外的线程,该线程读取包并进行解析他们到一个数组。我还有一个计时器,可用来更改时间间隔。在每个计时器刻度上,我都将数据源重新分配给DataGridView。

So I created an extra thread, which reads the packages and parses them to an Array. I also have a Timer, which I use to change the Interval. On every timer tick, I reassign the DataSource to the DataGridView.

有趣的是,当我这样做时,即使将计时器设置为0.1秒,它也只会每秒触发一次。如果我不刷新DataGridView,它会按照预期的那样每秒触发10次。

Interestingly, when I do, even if I set the timer to 0.1 seconds, it is only triggered about once a second. If I do not refresh the DataGridView, it gets triggered 10 times a second, as it is supposed to.

所以我假设我的DataGridView更新方法也是耗时的。但是我必须做些什么才能使其更高效,所以我可以每秒更新10次而没有任何问题?

So I am assuming that my method of updating the DataGridView is too time consuming. But what do I have to do to make it more efficient, so I can update it 10 times a second without any problems?

这是我使用的代码:

public MyForm()
    {
        InitializeComponent();

        timer = new System.Windows.Forms.Timer();
        timer.Interval = (1 * 1000); // 1 secs
        timer.Tick += new EventHandler(timer_Tick);
        timer.Start();

        readNetworkValues = true;
        networkReader = new Thread(() =>
        {
            Thread.CurrentThread.IsBackground = true;
            byte[] data = new byte[1024];
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 49003);
            UdpClient newsock = new UdpClient(ipep);
            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);

            while (readNetworkValues)
            {
                data = newsock.Receive(ref sender);
                dataSet = parseData(data); //Decrypts the data
            }
        newsock.Close();
        });
        networkReader.Start();
    }

    private void timer_Tick(object sender, EventArgs e)
    {
        if (dataSet != null)
        {
            lock (dataSet)
            {
                int currentRow = dataGrid.FirstDisplayedScrollingRowIndex;
                dataGrid.DataSource = dataSet;
                dataGrid.FirstDisplayedScrollingRowIndex = currentRow;
            }
        }
    }


推荐答案

您要更新的单元格数量以及您想要的更新速率足够高,足以引起闪烁滞后

The number of cells you want to update and also the update rate you want are high enough to cause flicker and lagging.

要避免这种情况,您可以为启用 DoubleBuffering DataGridView

To avoid it you can turn on DoubleBuffering for the DataGridView.

此属性默认情况下不公开。因此,可以选择

This property is not exposed by default. So have a have a choice of either


  • 创建子类

  • 通过 reflect

  • creating a subclass or
  • accessing it via reflection

此处是一个展示前者的帖子。它是为滚动闪烁而编写的,但也有助于避免更新滞后。该类可能看起来像这样:

Here is a post that demonstrates the former. It was written for a case of scrolling flicker but will help avoid update lags as well. The class can maybe look like this:

public class DBDataGridView : DataGridView
{
    public new bool DoubleBuffered
    {
        get { return base.DoubleBuffered; }
        set { base.DoubleBuffered = value; }
    }

    public DBDataGridView()
    {
        DoubleBuffered = true;
    }
}

您可以将此类添加到项目中,也可以简单地添加到

You can add this class to the project or simply to the form class (before the very last curly.) Compile and it will show up in the ToolBox.

另一个选项使用 reflection ;该表单类(在最后一次卷曲之前)将显示在工具箱中。这是一个通用函数,适用于任何类型的控件:

The other option uses reflection; here is a general-purpose function that should work for for any type of control:

using System.Reflection;

static void SetDoubleBuffer(Control ctl, bool DoubleBuffered)
{
    typeof(Control).InvokeMember("DoubleBuffered", 
        BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, 
        null, ctl, new object[] { DoubleBuffered });
}

两种方法都可以使 DoubleBuffering 随意打开和关闭;前者通过现在公开的属性,后者通过方法的 bool 参数实现。

Both ways let you turn DoubleBuffering on and off at will; the former via the now exposed property, the latter by the bool param of the method.

这篇关于非常频繁地更新datagridview的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆