我无法在合理的时间内使用 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;
}
}
}
最佳答案
您要更新的单元格数以及您想要的更新率足够高以导致闪烁和滞后.
要避免它,您可以为 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;
}
}
您可以将此类添加到项目或简单地添加到表单类(在最后一个 curl 之前。)编译,它将显示在工具箱中。
另一个选项使用反射;这是一个通用函数,适用于任何类型的控件:
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
;前者通过现在公开的 property,后者通过方法的 bool
参数。
关于c# - 非常频繁地更新datagridview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44185298/