つまり、イベント ループが現在キューにあるイベントを処理するようにします。VBA では、呼び出しの名前はDoEvents
です。
これをPerlでやりたい。できれば AnyEvent でこれを行うことをお勧めします。スクリプトを使用して記述したためです。しかし、ドキュメントにはそのような機能は見つかりませんでした。
ドキュメントにはイベントループを呼び出すと書かれているため、単純にcondvarで実装しようとしましたrecv
が、失敗しました。サンプルコードは次のとおりです。
use strict;
use warnings;
use AnyEvent;
use AnyEvent::Strict;
sub _long_task;
my $t1 = AE::timer 0, 3, sub{print"task 1, with interval 3 seconds\n";};
my $t2 = AE::timer 0, 7, sub{print"task 2, with interval 7 seconds\n";};
my $t3 = AE::timer 0, 11, sub{print"task 3, with interval 11 seconds\n";};
my $t_long = AE::timer 0, 0, \&_long_task;
sub DoEvents()
{
my $cv = AE::cv;
my $t = AE::timer 0, 0, sub { $cv->send; };
$cv->recv;
}
sub _long_task {
print"long task: ENTERING\n";
for(1..5) {
print"long task: doing some work for 2 seconds\n";
sleep 2;
print"long task: calling DoEvents\n";
DoEvents();
}
print"long task: EXITING, resheduling after 10 seconds\n";
$t_long = AE::timer 10, 0, \&_long_task;
}
AE::cv->recv;
出力は次のとおりです。
task 1, with interval 3 seconds
task 2, with interval 7 seconds
task 3, with interval 11 seconds
long task: ENTERING
long task: doing some work for 2 seconds
long task: calling DoEvents
AnyEvent::CondVar: recursive blocking wait attempted at C:\Users\andreyi\Desktop\try_event_loop.pl line 18.
更新: AnyEvent.pm に次の行があります。
$WAITING
and Carp::croak "AnyEvent::CondVar: recursive blocking wait attempted";
それらにコメントすると、DoEvents() が機能します。
ただし、この CPAN モジュールの変更を伴わない解決策を用意した方がよいでしょう。