(以下では、「実行」とは、同じプロセスで長時間実行され、wxExecuteまたはwxProcessを使用して外部プロセスを実行しないことを意味することを前提としています。)
実行ロジックを実行することにより、UIにクリックイベントを処理する機会が与えられていないため、「キャンセル」イベントはトリガーされません。
UIのブロックを回避するには、次のようなことを行う必要があります。[実行]ボタンをクリックすると、実行する関数の周りにコルーチンが作成されます。
coro = coroutine.create(myLongRunningFunction)
この時点でRunイベントが完了します。次に、EVT_IDLEイベントで、このコルーチンが完了していない限り、このコルーチンを再開します。次のようになります。
if coro then -- only if there is a coroutine to work on
local ok, res = coroutine.resume(coro, additional, parameters)
-- your function either yielded or returned
-- you may check ok to see if there was an error
-- res can tell you how far you are in the process
-- coro can return multiple values (just give them as parameters to yield)
if coroutine.status(coro) == 'dead' then -- finished or stopped with error
coro = nil
-- do whatever you need to do knowing the process is completed
end
end
他のイベントがトリガーされない限り、一部のオペレーティングシステムはIDLEイベントをトリガーしないため、プロセスが終了しない限り、おそらくIDLEイベントをさらに要求する必要があります。ハンドラーにパラメーターがあると仮定すると、さらにIDLEイベントを要求するためにevent
実行できます( RequestMore)。event:RequestMore(true)
実行時間の長いプロセスでは、適切なタイミングでcoroutine.yield()を呼び出す必要があります(切り替えに時間を浪費するので短すぎず、ユーザーがUIの遅延に気付くのに長すぎません)。おそらくこれを試す必要がありますが、呼び出しの間に100ミリ秒程度のタイマーベースのものが機能する可能性があります。
現在のように、IDLEイベントハンドラーまたは長時間実行関数のいずれかでキャンセル値を確認できます。私が説明したロジックは、アプリケーションUIにキャンセルイベントを期待どおりに処理する機会を与えます。