1

ユーザーがコンボボックスを選択してからボタンをクリックするフォーム「StartForm」があります。そこから私はしたいと思います:

  1. 別のフォーム「MainForm」のインスタンスを生成する

  2. そのフォームの DataGridView に約 50,000 行を入力します。

  3. データグリッド ビューの各行をループし、いくつかの処理を実行します。私の場合、セルの値に基づいて行の色をフォーマットし、いくつかの列を更新しています。

  4. フォームを表示します。

これは簡単ですが、多数の行とそれぞれの処理時間が原因で、MainForm を構築するときに UI がフリーズします。そのため、バックグラウンド スレッドで MainForm を構築する必要があり、進行中に StartForm を埋めるプログレス バーが必要です。

backgroundWorker を使用するとクロス スレッド例外が発生し続けるか、フォーマットが失われ、control.Invoke() も例外をスローするようです。たぶん私はこれらを正しく使用していないだけです...

誰かが上記を達成する方法を説明してもらえますか? 質問を理解できるように基本的なものにしようとしましたが、他の人に役立つかもしれませんが、私のコードが必要な場合はお尋ねください.

ありがとう!

4

2 に答える 2

2

データ グリッドに仮想モードを実装する必要があると思います。DataGridView Control での仮想モードの実装に関する msdn の記事をご覧ください。小さなサンプル:

grid.VirtualMode = true; // enable virtual mode
grid.RowCount = source.Count; // 50000
grid.CellValueNeeded += grid_CellValueNeeded;
grid.CellPainting += grid_CellPainting;

イベント ハンドラーを使用CellValueNeededして、セルに値を提供します (つまり、ソースから値を選択します)。イベント ハンドラーを使用CellPaintingして、セルの値に基づいてセルの色を設定します (e.CellStyleプロパティを使用)。ソースにデータを入力するのに時間がかかる場合は、BackgroundWorker でそれを行うことができます。ただし、仮想モードでデータのフォーマットと表示を行う - これは、大量の行がある場合に最適なオプションです (ちなみに、いくつかのフィルタリングを適用することを検討してください - ユーザーが一度に 50000 行のデータを必要とすることはめったにありません)。

于 2012-12-17T11:27:20.240 に答える
0

デフォルトでは、重い作業中に UI にアクセスできなくなるため、すべての作業は UI スレッドで行われ、「クラッシュ」したように見えます。UIスレッドではないスレッドでフォーム自体を作成することは可能ですが、フォームを作成したスレッドからのみフォームにアクセスできることを意味するため、それが必要な場合はほとんどありません。cross-thread exception別のスレッドから UI スレッドを変更しようとしているためです。

あなたが試みることができるのは、バックグラウンドスレッドですべてのデータを読み込んで処理することですが、それを新しい一時的なDataTable. 次に、UI スレッド (おそらく BackgroundWorker を使用している場合はイベント内) でDataSet.MergeRunWorkerCompletedを使用し、DataGridView にバインドされているメインの DataSet と一時的な DataTable をマージします。

これは、すべての処理と負荷の高い作業がバックグラウンド スレッドで行われることを意味しますが、DataGridViewコントロールは UI スレッドで更新されるため、無効なクロススレッドがバイパスされます。1 つの補足として、 のパフォーマンスをテストする必要がありますDataSet.Merge

于 2012-12-17T11:42:58.667 に答える