- PR -

イベントが頻発するようなWindowsアプリケーションの挙動について

投稿者投稿内容
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 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/
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2005-08-19 21:56
引用:

JKさんの書き込み (2005-08-19 13:01) より:
既存の通信ライブラリを使用しておりますので、通信部分の実装は
よく分かりません。ライブラリに用意されているイベントハンドラ
のデリゲート先を実装しているだけになります。


ちいとだけ気になるんですが、このライブラリのイベントって非同期で発生しますよね?
イベント自体はUIスレッドにちゃんとマーシャリングされるようになっているんでしょうか?
あるいはWindowsのメッセージでイベントが発生するような形とかになっているとか?

ところで、更新情報というのは、最大の想定(というかおかしくなってくるとき)で、
大体秒間何回くらいなんでしょう?
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 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イベントを明示的に発生させるとかしてませんか。(後者は別に問題ないのかな…)

後、ぼのぼのさんがおっしゃった事がヒントに「画面全体を再描画すると重い」。
「画面全体を再描画中に画面に表示すべきデータを全計算」すると重いですね。「もともと既に計算されて用意されているデータで画面全体を再描画」は軽い。「更新が必要な一部のデータだけ計算して、画面全体を再描画」も軽い。
ほげた
ベテラン
会議室デビュー日: 2002/05/08
投稿数: 67
お住まい・勤務地: なごやん
投稿日時: 2005-08-20 01:57
データサイズや更新頻度がわからないのでなんとも言えませんが
以下のような基本的なしきたりはやってますか?
・渋木宏明(ひどり)さんのおっしゃるように、データ入れ替えでなく詰め替えにする。
・無駄な描画更新がされないようにBeginUpdate()する。
・内部でイベントが発生しないようにBeginLoadData()する。
XSDを使っているのであれば、キー名指定のアクセスはしていないと思いますが
これもパフォーマンスを低下させる原因となります。

あと、なちゃさんの指摘にあるマーシャリングも匂いますね。
ハンドラで InvokeRequired が true になってないか見てみてください。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-08-20 15:19
具体的な数値が、何も上がっていないと思います。

データ更新の間隔(ミリ秒単位で)
1度に送られるデータのバイト数
転送に使われる回線の性能
要求性能(1秒間に何回再描画できなければならないか)

パッと思いつくのでこんなもん?
こういうのが上がってきて初めて、検証が開始できるんじゃないですか?
_________________
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2005-08-22 08:56
Lichtensteinさん、お早うございます。

#本題とは関係ありませんが…。

引用:

きくちゃんさんの、フラグを立てておくやり方は、
相当追い風を受ける開発になるので覚悟の上でどうぞ。


これって、どういう意味なんでしょうか?
逆風ってこと? だとしたら何故なんでしょうか…?
Lichtenstein
ベテラン
会議室デビュー日: 2003/11/06
投稿数: 61
投稿日時: 2005-08-22 09:22
>これって、どういう意味なんでしょうか?
>逆風ってこと? だとしたら何故なんでしょうか…?

「フラグを立てておく」と一言で済ませられるけれども、
実際には考慮しなければならないことが沢山あるかもしれないと思うからです。

2回フラグが立った場合、2回処理しなければいけない処理と、1回で
済む処理を分けるとか、
トランザクションとして管理すべき処理を見逃すかもしれないとか、そういうコストが
発生します。

タイミングの問題をデバッグするのも、コストが高いですし、
フラグが立ってから、画面を更新するまでの間が長いと苦情が入ったりします。

デリゲートの記述だけですませられるなら、それが一番手堅いし保守性も高いので。

>「更新データは1イベント毎に1rowずつサーバから飛んでくる」
>このイベントの頻度が具体的ではないと思いますが、なぜ、DataGridの
>パフォーマンスに問題があるという結論なのでしょうか?

イベントの頻度は書かれていないので、無視しました。

>また、「DataGridはWeb向けのクラスなので」はどういった意味でしょうか?

すみません。Web.UIしか思い出していませんでした。

きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2005-08-22 10:01
Lichtensteinさん、お早うございます。

引用:

「フラグを立てておく」と一言で済ませられるけれども、


ああ、そういうことですね。了解了解。
ちょっと、大雑把すぎたでしょうか。
イベントの発生ベースでの処理が間に合わないなら、順次処理でやっつけたらどうでしょう、というつもりでした。キューイングって言った方が良かったかも知れませんね。
いずれにしろ、事態がよく見えてなかったので、ざっくり、あんな感じの発言になりました。

スキルアップ/キャリアアップ(JOB@IT)