非常频繁地更新数据网格视图 [英] update datagridview very frequently

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

问题描述

我无法在合理的时间内在 C# 中刷新我的 DataGridView(顺便说一句,我是新手,我已经习惯了 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.

所以我创建了一个额外的线程,它读取包并将它们解析为一个数组.我还有一个定时器,我用它来改变间隔.在每次计时器滴答时,我将 DataSource 重新分配给 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.

为避免这种情况,您可以为 DataGridView 开启 DoubleBuffering.

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

  • 创建子类
  • 通过反射
  • 访问它

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

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.

另一个选项使用反射;这是一个适用于任何类型控件的通用函数:

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.

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

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