外部システムから受信したデータを表示する必要があるアプリケーションを構築しています。このデータは、すべての行が占有するバイト数が比較的少ない場合でも、非常に迅速に取得できます。これは、時間単位ごとに多くの行を追加する必要があることを意味します。私は現在、処理できるよりも速くデータを受信しているように見えるところにいます。つまり、メモリ使用量が増えています。
これの大部分は、実際の 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. */
パフォーマンスを向上させるためにできる比較的簡単なことはありますか? 処理がビジーである間はデータグリッドの描画を無効にし、完了したら描画することを考えていました。(好まれませんが) もう 1 つのことは、アイテムを受け取るたびに更新するのではなく、更新頻度を下げることです。(ただし、BindingList は、何かが追加されると DataGridView を自動的に更新するようです)
誰かが喜んで/できることを願っています。
-編集-
フォームの応答性は、特にしばらくしてから上記の方法でデータを処理しているときも同様に非常に悪いためです。(上記のプロセスはバックグラウンド ワーカーとバックグラウンド スレッドで行われますが)