Обновлять datagridview очень часто
У меня проблемы с обновлением моего DataGridView в разумные сроки в C# (что я новичок, кстати, я привык к 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;
}
}
}
1 ответ
Количество ячеек, которые вы хотите обновить, а также частота обновления, которую вы хотите, достаточно высоки, чтобы вызвать мерцание и отставание.
Чтобы избежать этого вы можете включить DoubleBuffering
для DataGridView
,
Это свойство не доступно по умолчанию. Так что есть выбор
- создание подкласса или
- доступ к нему через отражение
Вот пост, который демонстрирует первое. Он был написан для случая мерцания прокрутки, но также поможет избежать задержек при обновлении. Класс может выглядеть так:
public class DBDataGridView : DataGridView
{
public new bool DoubleBuffered
{
get { return base.DoubleBuffered; }
set { base.DoubleBuffered = value; }
}
public DBDataGridView()
{
DoubleBuffered = true;
}
}
Вы можете добавить этот класс в проект или просто в класс формы (до самого последнего вьющегося). Скомпилируйте, и он появится в ToolBox.
Другой вариант использует отражение; Вот функция общего назначения, которая должна работать для любого типа управления:
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
параметр метода.