0

私は Visual C++ アプリケーションに取り組んでおり、この作業の一部でファイルを圧縮解除します。これには、圧縮解除の進行状況を反映する進行状況バーを実装するために時間がかかる場合があるためです。

これは、デバッガーを使用して実行する場合は問題なく動作しますが、デバッガーを使用せずに実行したり、.exe ファイルから実行したりすると、進行状況バーが一貫して途中でスタックし (プログラムは機能を正常に完了しますが)、その後 100% にジャンプします。

プログレスバーの値を印刷することで、値が適切に設定されていることがわかりましたが、何らかの理由でこれが視覚的に反映されていません。

プログレスバー更新のコードは

while (mpeg.GetProgress() < 99){
            Console::Write(this->progressBar->Value);
            this->progressBar->Value = mpeg.GetProgress();
            this->progressBar->Update();
            Sleep(100);
        }

これは、プログラムのメイン スレッドで行われます。スリープは、コンソールでこれを追跡することが不可能であるため、更新が速すぎるのを防ぎます。

追跡が必要な関数は mpeg.Depackitise() です。これは別のスレッドで実行されるため、進行状況バーを継続的に更新できます。「進行状況」変数に関するコードは次のとおりです。

double Mpeg::GetProgress() {
return Mpeg::progress;
}

void Mpeg::SetProgress(double prog) {
Mpeg::progress = prog;
}

次のコードは、パケットごとにファイル全体を処理する for ループ内にあります。「packet」変数は現在のパケットで、「packet_count」はファイル内のパケットの総数です。これはすべて別の mpeg.Depackitise() スレッドで行われます。

        double Percent = 0.0;

    Percent = ((double)packet / (double)packet_count);
    SetProgress(Percent * 100);

誰かがそれを試すための解決策を提案できる場合は、非常に高く評価されます.これはしばらくの間私を悩ませてきました. オンラインで見つけたいくつかの提案では、初期化されていない変数を使用すると、デバッグの有無にかかわらず実行に違いが生じる可能性があるとのことでしたが、初期化されていない関連変数が見つかりません。

4

1 に答える 1

3

UI スレッドを絶対にブロックしてはなりません。

アプリケーションのメイン スレッドで大規模な計算を行っています。つまり、メッセージ ポンプに応答したり、画面上のコントロールの描画を描画/更新したりすることはできません。

質問の解決策として、マルチスレッドとメッセージパッシングを検討する必要があります。スレッドを開始し、そこで時間のかかる作業を行い、コールバックを使用してメイン スレッドの進行状況バーを更新します (メイン スレッド以外から UI に直接アクセスしないように注意してください!)。

于 2011-10-21T16:26:22.430 に答える