2

BackgroundWorker から DataGridView に一連の結果 (DataTable など) を「ストリーミング」する方法はありますか。私がやりたいことは、データをクエリし、結果が来るとDataGridViewに入力することです(SQL Server Management Studio のクエリ グリッドの結果のように)。私が最初に考えたのは、(UI のフリーズ効果を回避するために) BackgroundWorker を使用することでしたが、BackgroundWorker が結果を読み込んでいるため、認識可能な「ラグ」がまだあります。

これについて最善の方法は何ですか?

4

4 に答える 4

1

基になるコレクションを変更できるスレッドが1つしかない場合、これははるかにうまく機能します。私は読み取り専用のDGVを持っているので、行を追加/削除する唯一の方法は、基になるBindingSourceを操作することです。定期的にBindingSourceからアイテムを追加/削除する同期スレッドがあります。

私は1つの「トリッキーな」ことをしなければなりませんでした-更新されているアイテムが選択されたアイテムである場合、あなたはただ言うことはできません

myBindingSource[n] = newItem;

むしろ、新しいアイテムから既存のアイテムに値をディープコピーする必要があります。それ以外の場合は、「変更された」イベントをトリガーします。これにより、データソースにバインドされている他のすべてのものが再描画されます。参照コピーを実行するとちらつきが目立ち、ディープコピー(現在のアイテムのみ)に切り替えると修正されました。

もちろん、読み取り専用ビューとして使用するのではなく、フォームから直接データをユーザーにいじくり回させる場合は、まったく新しい(醜い!)ワームの缶を開くことになります。

于 2009-01-08T22:13:27.207 に答える
1

あなたは出来る:

DataGridView を最初は空の DataTable にバインドします。

次に、ワーカー スレッドでスレッド セーフなコレクション (同期キューなど) を使用し、Control.BeginInvoke を呼び出してレコード情報を UI スレッドに渡します。

UI スレッドでは、アイテムをキューから取り出し、対応する行を DataTable に追加します。データバインディングの魔法により、これらはグリッドビューに追加されます。

ただし、マルチスレッドを使用すると、すぐにプログラムが破損する可能性が高くなります。私はこの特定のスキームを試したことがなく、アイテムが追加されている間に GridView が事実上使用できなくなるかどうかはわかりません。マルチスレッドを使用してツリービューを作成しましたが、これは確かに素晴らしい効果です。ただし、考えられるすべてのユーザー操作を処理する完全に正しい実装ではないため、バグが発生したため、機能を無効にすることになりました。

于 2008-11-02T22:35:44.543 に答える
1

試してみましたが、これを行いました。アプリケーションとアーキテクチャは、私が入社する前に完成していました。私が行ったのは、「ページング」と非同期化でした。

彼らはすでにページングを含むストアド プロシージャを持っていたので、最初のリクエストで、合計結果の「サイズ」を (page1 のデータと共に) 送り返しました。

クライアント側で、空の行を DataTable に追加しました... ( 「RowNumber」フィールドを除いて空白)。

データのさらなるページ (非同期に受信された) で、行 [X] を取得し、その「ItemArray」を新しい配列に設定し、グリッドを更新します。例:

myDataGridView.Rows[rowNumber].SetValues(valuesFromNewPage);
于 2008-11-02T23:13:39.397 に答える
0

プロセスに2秒以内かかる場合は、「ビジー」カーソルを表示して、インラインで更新を実行します。これには2つの理由があります。

  • ほんの数秒しかかからない操作を開始した人は、操作が完了するまでに「集中」思考モードのままになります。無意識のうちに、彼はまだ自分の行動の結果を待っており、意識的な脳をその特定の焦点からまだ切り替えていません(アプリが「話中音」を示している限り)。

  • 上記のことを考えると、マルチスレッドの認知的オーバーヘッドは、それに付随するすべての危険を伴い、負担する価値はないと思います。

プロセスに最大5秒かかる場合は、最初に2秒以下に短縮することに集中します。繰り返しになりますが、通常、マルチスレッドを導入するよりも、パフォーマンスの向上に集中する方がはるかに簡単です(たとえば、SQLでページングすることによって)。BackgroundWorkerタイプを使用しても、マルチスレッドに関連する非順次の相互作用を分析して安全にすることは依然として困難です。

遅延を2秒以下に短縮する方法がない場合は、confuzatronが推奨する手法のようなものを使用できます。ただし、それでも、エンドユーザーは2秒以上待機した後にコンテキストスイッチを使用するため、進行状況ダイアログをエンドユーザーに表示することをお勧めします。進行状況ダイアログは、彼がいつあなたの文脈に焦点を合わせることに戻ることができるかについての彼に吸収しやすい情報を与えます。

于 2008-11-03T14:59:04.107 に答える