Я имею в виду, что вы делаете async_wait на таймере asio и привязываете обновление к функции, которая ссылается на тип T. Предположим, вы создали T изначально в стеке, прежде чем передавать его в async_wait. В конце этого async_wait он вызывает async_wait, обновляя таймер снова и снова. Оставляет ли этот стек тип T оставаться в живых до тех пор, пока первый таймер не восстановит себя, или после первого вызова функции T не выйдет из области видимости?Когда таймер asio выходит из области видимости?
ответ
У меня нет опыта работы с таймерами asio. Но если вы делаете
void somefunc(void)
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
}
Тогда таймер выходит за рамки, когда он выходит из функции. Так что с этим кодом ждать не будет. Если вы добавите t.wait() в этот код, он будет ждать 5 секунд и выйти из функции, а таймер выходит за рамки.
void somefunc(void)
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
t.async_wait(somecallback);
io.run();
}
Во втором примере таймер выходит из области действия при выходе из функции.
Если вы хотите обойти таймер, я думаю, вы должны написать вот так.
void somefunc(void)
{
boost::asio::io_service io;
while(something)
{
boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
t.async_wait(somecallback);
io.run();
}
}
Это будет держать таймер в стеке на один оборот в цикле, а затем воссоздан. Если вы поместите таймер вне цикла, он никогда не выйдет за рамки. Но тогда вы должны сбросить его, когда-либо переходите в цикл. Но я не вижу такой функции.
EDIT: В примере async_wait(), таймер будет уничтожить, из области видимости, непосредственно без отделки, если вы не имеете io.run(), чтобы сделать его ждать. И я бы предположил, что дескриптор deadline_timer() выполнит отмену таймера, когда он попадет в деструктор.
Если вы должны написать функцию, в которой вы создаете таймер в стеке, тогда вызовите async_wait, таймер будет уничтожен в конце вызова функции, и обратный вызов немедленно вызовет с правильным параметром ошибки.
Вы не можете передать объект таймера обратному вызову с помощью boost :: bind, поскольку объект не может быть скопирован.
Тем не менее вы можете управлять своим связующим в куче, передавая общий указатель при каждом вызове async_wait. Это может выглядеть так:
void MyClass::addTimer(int milliseconds) // Initial timer creation call
{
boost::shared_ptr<boost::asio::deadline_timer> t
(new boost::asio::deadline_timer
(m_io_service,
boost::posix_time::milliseconds(milliseconds)));
// Timer object is being passed to the handler
t->async_wait(boost::bind(&MyClass::handle_timer,
this,
t,
milliseconds));
}
void MyClass::handle_timer(boost::shared_ptr<boost::asio::deadline_timer> & t,
int milliseconds)
{
// Push the expiry back using the same tick
t->expires_at(t->expires_at() + boost::posix_time::milliseconds(milliseconds));
t->async_wait(boost::bind(&MyClass::handle_timer,
this,
t,
milliseconds));
onTimer(); // Do something useful
}
Фактический код, пожалуйста? :) – vladr
Было бы неплохо, если бы вы могли лучше объяснить, как вы хотите использовать async_wait(). Может быть, с помощью кода или мета кода. Возможно, вам нужно будет сделать так, как в ответе small_ducks, и создать таймер с новым, чтобы передать его другим функциям и получить необходимый эффект. – jpyllman