Я создаю приложение, которое должно отображать данные, полученные из внешней системы. Эти данные могут поступать очень быстро, в то время как количество байтов, занимаемых каждой строкой, относительно невелико. Это означает, что за единицу времени нужно добавлять много строк. В настоящее время я нахожусь в точке, где кажется, что я получаю данные быстрее, чем могу обработать, что означает, что использование моей памяти увеличивается.
Я думаю, что большая часть этого связана с отрисовкой фактического dataGridView. Я немного подправил dataGridView в надежде, что он уже повысит производительность. (например, отключить автоматический размер, специальные стили и т. д.)
В недавнем дополнении я добавил раскраску строк, которая и требовалась. В настоящее время мое приложение работает следующим образом:
- Я получаю данные из внешней системы
- Я помещаю данные в очередь (ConcurrencyQueue) по потоку
- Другой поток получает данные из этой очереди, обрабатывает их и добавляет в BindingList, привязанный к таблице.
Фактическое добавление происходит в функции, которая имеет 2 параметра: 1. Список, содержащий элементы для столбцов (элементов) 2. Цвет для строки. (Цвет)
это выглядит так (полу-псевдо):
/* Store the color for the row in the color list so it is accessible from the event */
rowColors.Add(rowColor); //Class variable that stored the colors of the rows used in the DataGridCellFormatting event
/* Create the row that is to be added. */
ResultRow resultRow = new ResultRow();
foreach(item in items)
{
resultRow.Set(item); /* It's actually a dictionary because some fields are optional, hence this instead of a direct constructor call) */
}
bindingList.Add(resultRow);
/* Row coloring based on error is done in the OnCellFormatting() */
/* Auto scroll down */
if (dataGrid.Rows.Count > 0)
{
dataGrid.FirstDisplayedScrollingRowIndex = dataGrid.Rows.Count - 1;
}
Как видно из приведенного выше кода, цвет, который я получаю, добавляется в список, который используется в событии datagridview следующим образом:
void DataGridCellFormattingEvent(object sender, DataGridViewCellFormattingEventArgs e)
{
// done by column so it happens once per row
if (e.ColumnIndex == dataGrid.Columns["Errors"].Index)
{
dataGrid.Rows[e.RowIndex].DefaultCellStyle.BackColor = rowColors[e.RowIndex];
}
}
BindingList определяется следующим образом:
BindingList bindingList;
где ResultRow - это класс с такой структурой:
public class ResultRow
{
private int first = 0;
private string second = "";
private UInt64 third = 0;
private IPAddress fourth = null;
//etc
public ResultRow()
{
}
public void Set (<the values>) //In actuallity a KeyValuePair
{
//field gets set here
}
public UInt64 Third
{
get { return third; }
set { third = value; }
}
/* etc. */
Могу ли я сделать что-нибудь относительно простое, чтобы повысить производительность? Я думал о том, чтобы, возможно, отключить рисование сетки данных, пока обработка занята, и рисовать, когда это будет сделано. (хотя и не желательно) Еще одна вещь, возможно, обновляется реже, а не после каждого полученного элемента. (BindingList, похоже, автоматически обновляет DataGridView, когда к нему что-то добавляется)
Я надеюсь, что кто-то захочет / сможет помочь.
-редактировать-
Отзывчивость формы тоже очень плохая, когда она обрабатывает данные описанным выше способом, особенно по прошествии некоторого времени. (несмотря на то, что описанный выше процесс происходит в фоновых работниках и фоновых потоках)