1

wxWidgets で作成している GUI アプリがあります。機能の一部として、GUI ウィンドウの操作と同時に「タスク」を実行する必要があります。たとえば、次のコードを実行します。

long currentTime = wxGetLocalTime();
long stopTime = wxGetLocalTime() + 3;
while (wxGetLocalTime() != stopTime) {}
wxMessageBox("DONE IN APP");

この 3 秒間、wxMessageBox が表示されるまで、アプリケーションは基本的にフリーズします。複数のスレッドを使用せずにこれをバックグラウンドで実行する方法はありますか? 私が開発しているアプリケーションに問題が生じます。

使用できるイベント処理の種類があるかどうか疑問に思っていました。どんな種類の助けも大歓迎です。

4

3 に答える 3

6

GUI wx アプリケーションで時間のかかるタスクを実行するには、次の 3 つの方法があります。

  1. 最も好ましいのは、別のスレッドを使用することです。アプリケーションが「非常に GUI に集中している」という説明は、私にはまったく意味がありません。GUI の集中度 (それが何であれ) によってバックグラウンド ワーカー スレッドを使用できない場合は、プログラムの設計を真剣に再考する必要があると思います。このアプローチを使用する場合は、非常に単純ですが、スレッド/プログラムの終了の問題に特に注意してください。特に、スレッドが終了するのを待つか (実行に時間がかからない場合は許容可能)、プログラムを終了する前に明示的にスレッドをキャンセルする必要があります。

  2. EVT_IDLE他に処理するイベントがない場合は、イベントを使用してタスクを実行します。これは、ハンドラーで処理を再開できるようにする必要があるため、十分に小さな断片に分割できる小さなタスクにとってそれほど悪くはありません。event.RequestMore()他に何も起こっていない場合でも、アイドル イベントを取得し続けるために呼び出すことを忘れないでください。

  3. 最悪で最も危険なのはwxYield()、別の回答で示唆されているように電話することです。これは最初は簡単に思えるかもしれません、コード内で再入可能性の問題をデバッグするのが非常に困難になる可能性があるため、後で後悔することになります。使用する場合は、どこでも再入可能であることを防ぐ必要があり、この関数が正確に何をするのかを本当に理解する必要があります。

于 2012-12-18T13:51:53.190 に答える
3

私はこれがゲームに遅れていることを知っていますが...

私は EVT_IDLE メソッドを YEARS に使用することに成功しました (Motif を使用した 90 年代にさかのぼります)。主なアイデアは、タスクを小さなピースに分割し、各ピースが次のピースを呼び出すことです (リンクされたリストを考えてください)。これを行うメカニズムは、CallAfter() メソッドを使用することです (もちろん C++ を使用します)。ピースの最後のステップとして "CallAfter()" を実行するだけで、GUI メイン ループが別の反復を実行し、次のピースを呼び出す前に GUI 要素などを更新できるようになります。ピースを小さく保つことを忘れないでください。

バックグラウンド スレッドを使用するのは非常に優れていますが、想像以上に難しい場合があります...最終的には. バックグラウンドで作業しているデータが他のものに触れたり閲覧されたりしないことがわかっている限り、問題ありません。これが事実であることがわかっている場合は、それが進むべき道です。この方法により、バックグラウンドでの計算中 (ウィンドウのサイズ変更/移動など) に GUI を完全に応答させることができます。

どちらの場合でも、同じバックグラウンド タスクを誤って複数回起動しないように、最初のステップとして適切な GUI 要素の感度を下げることを忘れないでください (たとえば、バックグラウンド スレッドを起動するプッシュ ボタンを連続して複数回誤ってクリックするなど)。 .

于 2015-11-18T14:55:04.047 に答える
3

これを試して:

long currentTime = wxGetLocalTime();
long stopTime = wxGetLocalTime() + 3;
while (wxGetLocalTime() != stopTime) {
   wxYield();
}
wxMessageBox("DONE IN APP");
于 2012-12-17T23:47:27.313 に答える