Cuando intento obtener (no establecido) el tiempo de caducidad actual usando boost expires_from_now() parece cancelar realmente el temporizador, pero en realidad funciona como se esperaba, pero finalmente no llama al controlador.¿Por qué la función impulso asio expires_from_now() cancelar un deadline_timer?
O, en otras palabras, al acceder a un deadline_timer con expires_from_now() llamará al controlador inmediatamente y no llamará al controlador cuando caduque.
Por favor, considere el siguiente código y la correspondiente salida:
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <iostream>
using namespace boost::posix_time;
using namespace std;
void handler1(const boost::system::error_code &ec)
{
if (ec == boost::asio::error::operation_aborted)
{
std::cout << microsec_clock::local_time() << " Handler1: Timer 1 was cancelled or retriggered." << std::endl;
}
else
{
std::cout << microsec_clock::local_time() << " Handler1: expired." << std::endl;
}
}
boost::asio::io_service io_service1;
class Mytimer {
public:
Mytimer();
void startTimer();
void runTimerThread();
bool isRunning();
private:
bool m_isRunning;
boost::asio::deadline_timer* m_pTimer;
boost::thread* m_pThread;
};
Mytimer::Mytimer()
: m_pTimer(NULL),
m_pThread(NULL)
{
m_pTimer = new boost::asio::deadline_timer(io_service1);
m_pTimer->async_wait(handler1);
}
void Mytimer::runTimerThread()
{
io_service1.run();
}
void Mytimer::startTimer()
{
m_pThread = new boost::thread(&Mytimer::runTimerThread, this);
m_pTimer->expires_from_now(boost::posix_time::seconds(10));
}
bool Mytimer::isRunning()
{
time_duration td = m_pTimer->expires_from_now();
if (td.total_seconds() > 0)
{
return true;
}
return false;
}
int main()
{
time_facet *facet = new time_facet("%Y%m%d %H:%M:%S%f");
std::cout.imbue(std::locale(std::cout.getloc(), facet));
cout << microsec_clock::local_time() << " before timer construction" << endl;
Mytimer timer;
cout << microsec_clock::local_time() << " before startTimer()" << endl;
timer.startTimer();
cout << microsec_clock::local_time() << " IsRunning: " << timer.isRunning() << endl;
for (int i = 0; i <= 20; i++)
{
sleep(1);
cout << microsec_clock::local_time() << " IsRunning: " << timer.isRunning() << endl;
}
}
20120412 22: 41: 45689235 antes de la construcción del temporizador
20120412 22: 41: 45689514 antes startTimer()
20120412 22:41: 45689619 IsRunning: 1
20120412 22: 41: 45689693 Handler1: temporizador 1 fue cancelada o reactivar.
20120412 22: 41: 46689792 IsRunning: 1
20120412 22: 41: 47689994 IsRunning: 1
20120412 22: 41: 48690179 IsRunning: 1
20120412 22: 41: 49690375 IsRunning: 1
20120412 22:41 : 50690530 IsRunning: 1
20120412 22: 41: 51690712 IsRunning: 1
20120412 22: 41: 52690884 IsRunning: 1
20120412 22: 41: 53691069 IsRunning: 1
20120412 22: 41: 54691236 IsRunning: 0
20120412 22: 41: 55691428 IsRunning: 0
20120412 22: 41: 56691614 IsRunning: 0
20120412 22: 41: 57691810 IsRunning: 0
20120412 22: 41: 58692001 IsRunning: 0
20120412 22: 41: 59692193 IsRunning: 0
20120412 22:42 : 00692364 IsRunning: 0
20120412 22: 42: 01692542 IsRunning: 0
20120412 22: 42: 02692706 IsRunning: 0
20120412 22: 42: 03692886 IsRunning: 0
20120412 22: 42: 04693071 IsRunning: 0
20120412 22: 42: 05693267 IsRunning: 0
20120412 22: 42: 06693465 IsRunning: 0
Creo que hay dos problemas aquí: Primero, en el constructor se llama al temporizador sin ninguna duración de caducidad, por lo que caducará inmediatamente. En segundo lugar, cuando la función miembro reinicia el temporizador, no hay controlador. Así que expires_from_now aún funciona (como se puede ver el 1 cambia a 0 después de 10 segundos), pero nunca se llamará al controlador, porque no hay ninguno asociado. –
Mantendré la pregunta abierta por ahora, tal vez alguien pueda confirmar mis conclusiones. –
+1 para el reproductor –