2010-03-13 12 views
5

Quello che intendo è, diciamo che fai un async_wait su un timer asio e leghi l'aggiornamento a una funzione che prende un riferimento a un tipo T. Diciamo che hai creato il T inizialmente nello stack prima di passarlo a async_wait. Alla fine di tale async_wait, chiama async_wait stesso, rinnovando il timer più e più volte. Lo stack allocato al tipo T rimane attivo fino alla prima volta in cui il timer non si rinnova da solo, o dopo la prima chiamata della funzione, il T esce dal campo di applicazione?Quando un temporizzatore asio esce dal campo di applicazione?

+0

Codice effettivo per favore? :) – vladr

+0

Sarebbe bello se potessi spiegare meglio come vuoi usare async_wait(). Forse con qualche codice o meta-codice. Forse devi fare come in risposta small_ducks e creare il timer con nuovo per passarlo ad altre funzioni e ottenere l'effetto desiderato. – jpyllman

risposta

0

Non ho esperienza con gli asio timer. Ma se lo fai

void somefunc(void) 
{ 
    boost::asio::io_service io; 

    boost::asio::deadline_timer t(io, boost::posix_time::seconds(5)); 
} 

Quindi il timer è fuori dall'ambito quando esce dalla funzione. Quindi con questo codice nessuna attesa può mai succedere. Se aggiungi t.wait() a quel codice, aspetterà 5 secondi e uscirà dalla funzione e il timer non rientra nello scope.

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(); 
} 

Nel secondo esempio il timer esce dall'ambito quando la funzione viene chiusa.

Se si desidera aggirare il timer, credo che si debba scrivere in questo modo.

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(); 
    } 
} 

Ciò manterrà il timer in pila per un giro nel ciclo, quindi verrà ricreato. Se metti il ​​timer fuori dal giro non andrà mai fuori portata. Ma poi devi resettarlo in qualche modo per accendere il loop. Ma non vedo alcuna funzione del genere.

EDIT: Nell'esempio di async_wait(), il timer sarà distruggere, fuori portata, direttamente senza fine se non si ha l'io.run() per renderlo aspettare. E suppongo che l'autore di deadline_timer() esegua un annullamento del timer quando colpisce il distruttore.

8

Se si desidera scrivere una funzione in cui si crea un timer nello stack, quindi chiamare async_wait, il timer verrà distrutto al termine della chiamata della funzione e il callback immediatamente chiamato con il parametro di errore corretto.

Non è possibile passare l'oggetto timer alla richiamata utilizzando boost :: bind, poiché l'oggetto non è copiabile.

Tuttavia, è possibile gestire il raccoglitore sull'heap, passando un puntatore condiviso su ogni chiamata su async_wait. Potrebbe essere il seguente:

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 
} 
Problemi correlati