Кажется, что ответ для поведения лежит в документации для basic_waitable_timer::expires_at(const time_point & expiry_time)
:
Эта функция устанавливает время истечения. Любые ожидающие асинхронные операции ожидания будут отменены. Обработчик для каждой отмененной операции будет вызываться с кодом ошибки boost :: asio :: error :: operation_aborted.
blockquote>В вашем примере, когда заканчивается первый таймер, он вызывает
expires_at
, чтобы переслать таймер на секунду. Однако это отменяет второй запущенный вызов await, который теперь будет вызываться непосредственно на следующей итерации цикла с ошибкойoperation_aborted
. Однако, поскольку вы не проверяете код ошибкиec
, вы этого не видите. Теперь этот обработчик будет снова напрямую пересылать таймер и тем самым отменять последнийasync_wait
, который был запущен.Это продолжается до тех пор, пока обработчики не отменят себя достаточно часто, чтобы
count==0
работал только один таймер. Поскольку дата истечения срока пересылается каждый раз по 1 с, код все еще ожидает истечения целых 40 с.
Глюк! Кажется, что проблема скрыта в предописании, которое я пропустил. Не знал что подлая функция.
Кажется, что компилятор полагает только, что первое объявление класса генерирует RTTI или не, итак, если у Вас есть предописание как это...
type
TMyClass = class;
...
...
{$METHODINFO ON}
TMyClass = class
private
fField: integer;
published
property Field: integer read fField write fField;
end;
{$METHODINFO OFF}
...
...
procedure TestRTTI;
begin
assert(assigned(GetPropInfo(TMyClass, 'Field')), 'WTF! No RTTI found!');
end;
... Вы получите ошибку утверждения. Так, для того, чтобы разобраться в RTTI, нужно включить {$METHODINFO} директиву для предописания, как замечено здесь....
type
{$METHODINFO ON}
TMyClass = class;
{$METHODINFO OFF}
...
...
TMyClass = class
private
fField: integer;
published
property Field: integer read fField write fField;
end;
...
Я рад, что Вы нашли решение. Это - то же самое с $TypeInfo
директива. Справка Delphi 7 говорит:
Обратите внимание, что, если класс вперед объявляется, первое объявление класса должно быть объявлено с
$M
переключатель.
P.S.: $M+/- = $TypeInfo On/Off