2010-03-13 1 views
5

Я имею в виду, что вы делаете async_wait на таймере asio и привязываете обновление к функции, которая ссылается на тип T. Предположим, вы создали T изначально в стеке, прежде чем передавать его в async_wait. В конце этого async_wait он вызывает async_wait, обновляя таймер снова и снова. Оставляет ли этот стек тип T оставаться в живых до тех пор, пока первый таймер не восстановит себя, или после первого вызова функции T не выйдет из области видимости?Когда таймер asio выходит из области видимости?

+0

Фактический код, пожалуйста? :) – vladr

+0

Было бы неплохо, если бы вы могли лучше объяснить, как вы хотите использовать async_wait(). Может быть, с помощью кода или мета кода. Возможно, вам нужно будет сделать так, как в ответе small_ducks, и создать таймер с новым, чтобы передать его другим функциям и получить необходимый эффект. – jpyllman

ответ

0

У меня нет опыта работы с таймерами 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() выполнит отмену таймера, когда он попадет в деструктор.

8

Если вы должны написать функцию, в которой вы создаете таймер в стеке, тогда вызовите 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 
}