- - PR -
イベントが頻発するようなWindowsアプリケーションの挙動について
| 投稿者 | 投稿内容 | ||||
|---|---|---|---|---|---|
|
投稿日時: 2005-08-19 21:17
「既存のアプリ」が「コントロールをカスタマイズ」しているならなおのこと、.NET アプリケーションでも「高負荷をキューでしのぎ、落ち着いたら再描画する」という手法で乗り切るのもありなんじゃないですか? ただ、私が直接担当したプロジェクトではありませんが、ログ表示に WinForm の DataGrid を使用していて「表示が遅い」といって嘆いているのを目撃したことがあります。 表示データの量が 1000 行・数カラム程度なら、リストビューを使った方がかなり速いと思います。 ただし、リストビューアイテムの再充填(=Items.Clear() してから Items.Add() の繰り返し)はやっちゃ駄目です。 リストビューに表示されている各項目のプロパティを再設定して回るのが最速です。 _________________ // 渋木宏明 (Hiroaki SHIBUKI) // http://hidori.jp/ // Microsoft MVP for Visual C# // // @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/ | ||||
|
投稿日時: 2005-08-19 21:56
ちいとだけ気になるんですが、このライブラリのイベントって非同期で発生しますよね? イベント自体はUIスレッドにちゃんとマーシャリングされるようになっているんでしょうか? あるいはWindowsのメッセージでイベントが発生するような形とかになっているとか? ところで、更新情報というのは、最大の想定(というかおかしくなってくるとき)で、 大体秒間何回くらいなんでしょう? | ||||
|
投稿日時: 2005-08-19 22:22
例)
dataGrid1.DataSource = dataTable private void SetData() { for(int i = 0; i < 10000; i++) { DataRow row = dataTable.NewRow(); dataTable.Rows.Add(row); } } private void button1_Click(object sender, System.EventArgs e) { ThreadStart start = new ThreadStart(SetData); Thread thread = new Thread(start); thread.Start(); } とした場合、butto1クリック押下したとき、負荷はかかってますが、とりあえず連続的にグリッドに表示しながらです。その間ウィンドウ自体もいろいろ動かせます。 今回のJKさんの場合とは違いますが、上記は JKさんの場合のイベントが休みなく呼ばれたときに似ています。(マルチスレッドにしてますが) DataGrid は DataSource の状況が変わったとき、自分自身で再描画しているようです。 とりあえず、DataGridやDataSetのパフォーマンス云々は置いておいて…。 Paintイベント処理中に何かしてませんか?または、Paintイベントを明示的に発生させるとかしてませんか。(後者は別に問題ないのかな…) 後、ぼのぼのさんがおっしゃった事がヒントに「画面全体を再描画すると重い」。 「画面全体を再描画中に画面に表示すべきデータを全計算」すると重いですね。「もともと既に計算されて用意されているデータで画面全体を再描画」は軽い。「更新が必要な一部のデータだけ計算して、画面全体を再描画」も軽い。 | ||||
|
投稿日時: 2005-08-20 01:57
データサイズや更新頻度がわからないのでなんとも言えませんが
以下のような基本的なしきたりはやってますか? ・渋木宏明(ひどり)さんのおっしゃるように、データ入れ替えでなく詰め替えにする。 ・無駄な描画更新がされないようにBeginUpdate()する。 ・内部でイベントが発生しないようにBeginLoadData()する。 XSDを使っているのであれば、キー名指定のアクセスはしていないと思いますが これもパフォーマンスを低下させる原因となります。 あと、なちゃさんの指摘にあるマーシャリングも匂いますね。 ハンドラで InvokeRequired が true になってないか見てみてください。 | ||||
|
投稿日時: 2005-08-20 15:19
具体的な数値が、何も上がっていないと思います。
データ更新の間隔(ミリ秒単位で) 1度に送られるデータのバイト数 転送に使われる回線の性能 要求性能(1秒間に何回再描画できなければならないか) パッと思いつくのでこんなもん? こういうのが上がってきて初めて、検証が開始できるんじゃないですか? _________________ | ||||
|
投稿日時: 2005-08-22 08:56
Lichtensteinさん、お早うございます。
#本題とは関係ありませんが…。
これって、どういう意味なんでしょうか? 逆風ってこと? だとしたら何故なんでしょうか…? | ||||
|
投稿日時: 2005-08-22 09:22
>これって、どういう意味なんでしょうか?
>逆風ってこと? だとしたら何故なんでしょうか…? 「フラグを立てておく」と一言で済ませられるけれども、 実際には考慮しなければならないことが沢山あるかもしれないと思うからです。 2回フラグが立った場合、2回処理しなければいけない処理と、1回で 済む処理を分けるとか、 トランザクションとして管理すべき処理を見逃すかもしれないとか、そういうコストが 発生します。 タイミングの問題をデバッグするのも、コストが高いですし、 フラグが立ってから、画面を更新するまでの間が長いと苦情が入ったりします。 デリゲートの記述だけですませられるなら、それが一番手堅いし保守性も高いので。 >「更新データは1イベント毎に1rowずつサーバから飛んでくる」 >このイベントの頻度が具体的ではないと思いますが、なぜ、DataGridの >パフォーマンスに問題があるという結論なのでしょうか? イベントの頻度は書かれていないので、無視しました。 >また、「DataGridはWeb向けのクラスなので」はどういった意味でしょうか? すみません。Web.UIしか思い出していませんでした。 | ||||
|
投稿日時: 2005-08-22 10:01
Lichtensteinさん、お早うございます。
ああ、そういうことですね。了解了解。 ちょっと、大雑把すぎたでしょうか。 イベントの発生ベースでの処理が間に合わないなら、順次処理でやっつけたらどうでしょう、というつもりでした。キューイングって言った方が良かったかも知れませんね。 いずれにしろ、事態がよく見えてなかったので、ざっくり、あんな感じの発言になりました。 | ||||
