ゲージが進まない

解決


ニトロ  2008-07-14 20:20:16  No: 31223

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


HOta  2008-07-15 03:54:41  No: 31224

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


DEKO  2008-07-15 04:57:23  No: 31225

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

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-15 06:15:31  No: 31226

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


ニトロ  2008-07-15 08:19:06  No: 31227

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

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


DEKO  2008-07-15 09:57:48  No: 31228

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

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

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


ニトロ  2008-07-15 21:05:41  No: 31229

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


ニトロ  2008-07-17 01:02:22  No: 31230

.                                                              
解決


ニトロ  2008-07-17 01:22:47  No: 31231

チェック忘れだね


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加