問題タブ [c++builder-10.1-berlin]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - Embarcadero C++Builder でイベント ハンドラは再入可能ですか?
Embarcadero CB10.1 の再入可能性に関する問題の処理方法について、アドバイスをお願いしたいと思います。「すべての最適化を無効にする」を true に設定して、デバッグ構成でコンパイルします。私はWin7で実行しています。
簡単なテストケースがあります。2 つのボタンがあるフォーム。各ボタンの OnClick イベント ハンドラーは、CPU を集中的に使用する同じ関数を呼び出します。以下は、ヘッダー ファイルとそれに続くプログラム ファイルです。
- 1 番目のケース: 表示されているコードですが、ProcessMessages() への呼び出しはありません。
これを実行してボタン 1 をクリックすると、CPU 使用率が約 9 秒間ほぼ 100% に跳ね上がります。この間、フォームは応答しなくなります。フォームを移動したり、ボタン 2 をクリックしたりできません。
それは私が期待するように機能します。
2 番目のケース : CPU を集中的に使用する機能中にフォームをユーザーに応答させるために、示されているように ProcessMessages() 呼び出しを追加しました。これで、フォームを移動して他のボタンをクリックできるようになりました。
ボタン 1 をもう一度クリックしたり、ボタン 2 をクリックしたりすることもできるため、これは必ずしも良いことではありません。CPU を集中的に使用する関数が 2 回目に実行されるのを防ぐために、静的なブール値フラグ "InUse" を作成しました。関数の開始時に設定し、関数の完了時にクリアします。
そのため、CPU を集中的に使用する関数に入ったときにフラグを確認し、フラグが設定されている場合 (ボタンを前回クリックして設定されている必要があります)、メッセージを表示してフラグがクリアされるのを待ちます。
しかし、フラグはクリアされず、私のプログラムは「while」ステートメントで永遠にループします。CPU を集中的に使用する関数が完了するのを待ってから、もう一度実行するようにプログラムを設定したいと思います。
デッドロックに達した後に Spin() 関数にブレークポイントを設定すると、どちらのイベントも実行されていないことが示され、決して起動されません。
VCL がスレッド セーフではないことはわかっていますが、ここではすべての処理がメイン スレッドで行われます。私の実際のコードでは、VCL 関数の呼び出しが多いため、CPU を集中的に使用する関数はメイン スレッドに残す必要があります。
クリティカル セクションとミューテックスを検討しましたが、すべてがメイン スレッドにあるため、それらを使用してもブロックされません。
多分それはスタックの問題ですか?デッドロックなしでこれを処理できるソリューションはありますか?