非常频繁地更新datagridview
Posted
技术标签:
【中文标题】非常频繁地更新datagridview【英文标题】:update datagridview very frequently 【发布时间】:2017-05-25 16:21:11 【问题描述】:我无法在 C# 的合理时间内刷新我的 DataGridView(顺便说一句,我是新手,我已经习惯了 java...)。
我正在通过每秒发送 20 个包的网络获取数据。我想解析数据并将其放入 DataGridView 中。我还想调整 DataGridView 更新的时间间隔,从 0.1 秒到 1 分钟。
所以我创建了一个额外的线程,它读取包并将它们解析为一个数组。我还有一个计时器,我用它来更改间隔。在每个计时器滴答声中,我将 DataSource 重新分配给 DataGridView。
有趣的是,当我这样做时,即使我将计时器设置为 0.1 秒,它也只会每秒触发一次。如果我不刷新 DataGridView,它会按预期每秒触发 10 次。
所以我假设我更新 DataGridView 的方法太耗时了。但是我要怎么做才能让它更有效率,所以我可以每秒更新 10 次而没有任何问题呢?
这是我使用的代码:
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;
【问题讨论】:
timer.Interval = (1 * 1000); // 10 秒 不。 - 另外:请勿致电DataGridView
a GridView
或DataGrid
,反之亦然!!这是错误且令人困惑的,因为它们是不同的控件。始终以正确的名称称呼事物! - 另外:您要显示多少数据? 20 fps 比电影快;没有人能以这样的速度阅读任何东西!
对不起,我更正了我的问题,评论是一些旧代码的遗留问题。我不知道有这样的混乱,一开始就找不到 GridView。如前所述,我对 C# 完全陌生。 20fps 不是我的目标,但正如问题中所写,我希望至少有 10fps。我知道这很快,需要的是实时可见的数据更改。在大多数情况下,1 秒太慢了。除了我目前的问题,我还想知道究竟是什么导致了“滞后”,只是为了更好地学习和了解 C#。
GridView 和 DataGrid 是来自其他/旧框架(.Net 1.0、ASP、WPF)的控件。 - 延迟可能是由数据大小引起的。你显示多少数据。或者通过锁..
啊,很高兴知道......到目前为止,我已经用 20 行和 26 列测试了它,每列都包含一个相当短的字符串或双精度。我想将其扩展到大约 150 行,相同数量的列。我读过 C# 是相当线程安全的......锁是多余的吗?
哇,真是天才。我最终使用了这个奇怪的东西:typeof(DataGridView).InvokeMember("DoubleBuffered", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, null, dataGrid, new object[] true );
因为我不确定如何制作自定义类的 dataGrid ...如果您对此了解更多,如果您能详细说明为什么这在答案中有效,我将不胜感激.如果没有,无论如何都将其发布为答案,这样您就可以获得当之无愧的积分。非常感谢!
【参考方案1】:
您想要更新的单元格数量以及您想要的更新率足够高,足以导致闪烁和滞后。
为避免这种情况,您可以为DataGridView
启用DoubleBuffering
。
默认情况下不公开此属性。所以可以选择一个
创建子类或 通过反射访问它Here is a post 演示了前者。它是针对滚动闪烁的情况而编写的,但也有助于避免更新滞后。该类可能如下所示:
public class DBDataGridView : DataGridView
public new bool DoubleBuffered
get return base.DoubleBuffered;
set base.DoubleBuffered = value;
public DBDataGridView()
DoubleBuffered = true;
您可以将此类添加到项目中,也可以简单地添加到表单类中(在最后一个卷曲之前)。编译它会显示在工具箱中。
另一个选项使用反射;这是一个通用函数,适用于任何类型的控件:
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
参数。
【讨论】:
这对我来说是一个非常有用的信息。谢谢@TaW。以上是关于非常频繁地更新datagridview的主要内容,如果未能解决你的问题,请参考以下文章