ゲージが進まない

解決


ニトロ  2008-07-14 11:20:16  No: 31223  IP: 192.*.*.*

500万件程のデータが入っているテキストファイルのデータをDBにインポート
する時に、進行状況を表示する為ゲージを使用したいのですが、データが
大量にあるせいかゲージが進みません。というかアプリ自体がフリーズ(応答なし)の様な状態になってしまいます。数万件程度なら問題なくできました。
何か対策はありますでしょうか?

編集 削除
HOta  2008-07-14 18:54:41  No: 31224  IP: 192.*.*.*

Delphiのバージョンは何でしょうか?
使ったコンポーネントは、何でしょうか?
標準でゲージというのが有るのでしょうか?
フリーズして、全くインポートできないのでしょうか?
数万件の場合は、表示も変化して処理できるのでしょうか?

編集 削除
DEKO  2008-07-14 19:57:23  No: 31225  IP: 192.*.*.*

こんなんでどうでしょう。

var
  i: Integer;
  SL: TStringList;
begin
  SL := TStringList.Create;
  try
    SL.LoadFromFile('ほにゃらら');
    ProgressBar1.Min := 0;
    ProgressBar1.Max := 100;
    ProgressBar1.Position := 0;
    for i:=0 to SL.Count-1 do
      begin
        if (i mod 100) = 0 then
          begin
            ProgressBar1.Position := (i * 100) div (SL.Count-1);
            Application.ProcessMessages;
          end;

        // 処理

      end;
    ProgressBar1.Position := ProgressBar1.Max;
    Application.ProcessMessages;
  finally
    SL.Free;
  end;
end;

大量にデータがある場合、Application.ProcessMessagesを挟まないと
ゲージの描画が更新されずにフリーズ状態のように見えます。

だからと言って普通にループにApplication.ProcessMessagesを挟むと
今度はApplication.ProcessMessagesに時間を取られて処理完了に
時間が掛かるようになります。

上記サンプルでは100ループに一回、画面の更新が行われるようになっています。

> 標準でゲージというのが有るのでしょうか?
[Samples]にあるTGaugeの事かと。
上記サンプルソースではTGaugeではなく
[Common Controls]にあるTProgressBarを利用していますが。

# TGaugeへの改変は難しくないと思います。

古いDelphiでは、TGaugeのMinValue/MaxValue/Progressの型が小さく
(16bit Integerだったかな?)
あまり大きな値をMaxValue/Progressにセットすると
ゲージが正常に進まなくなるという問題があった気がします。

# そのため、私は今でもゲージ(プログレスバー)の範囲を
# 0-100固定にし、位置を100分率計算しています。

編集 削除
ニトロ  2008-07-14 21:15:31  No: 31226  IP: 192.*.*.*

説明不足で申し訳ありません
Delphiのバージョンは何でしょうか?→Delphi7です
使ったコンポーネントは、何でしょうか?→[Samples]にあるTGaugeです
標準でゲージというのが有るのでしょうか?
フリーズして、全くインポートできないのでしょうか?
→処理自体は出来ています。
数万件の場合は、表示も変化して処理できるのでしょうか?
→全く問題ありません。

編集 削除
ニトロ  2008-07-14 23:19:06  No: 31227  IP: 192.*.*.*

DEKOさん
この様な現象があるとは知りませんでした。
勉強になりました。

このゲージは実行ボタンを押した時に別のフォームを表示して(ダイアログの様な感じ)そこに貼り付けているのですが、そのフォームのゲージに下に
「更新中・・・」というラベルも貼り付けているのですが、文字が表示されません。やはり同じ原因なのでしょうか?

編集 削除
DEKO  2008-07-15 00:57:48  No: 31228  IP: 192.*.*.*

>やはり同じ原因なのでしょうか?
ソースを見た訳ではないので何とも言えませんが、
一般的にはApplication.ProcessMessagesを挟まなければそうなりますね。

D7のHelpにはこう書いてあると思います。

メッセージ処理を無視すると,ProcessMessages メソッドを呼び出すアプリケーションだけに影響し,そうでないアプリケーションには影響しません。時間のかかる処理を行うときに ProcessMessages を定期的に呼び出すようにすれば,アプリケーションが描画や他のメッセージに応答することが可能になります。

編集 削除
ニトロ  2008-07-15 12:05:41  No: 31229  IP: 192.*.*.*

Application.ProcessMessagesを挟むことで、ゲージ、ラベル共に
問題を解決できました。
大量のデータを扱ったことがなかった為、初めての現象でしたが、
勉強になりました。
ありがとうございます。

編集 削除
ニトロ  2008-07-16 16:02:22  No: 31230  IP: 192.*.*.*

.                                                              
解決

編集 削除
ニトロ  2008-07-16 16:22:47  No: 31231  IP: 192.*.*.*

チェック忘れだね

編集 削除