Was ich meine ist, nehmen wir an, dass Sie eine async_wait auf einem Asio-Timer ausführen und das Update an eine Funktion binden, die einen Verweis auf einen Typ T annimmt. Nehmen wir an, Sie haben das T zunächst auf dem Stapel erstellt, bevor es an async_wait übergeben wurde. Am Ende dieser async_wait ruft es async_wait selbst auf und erneuert den Timer immer wieder. Bleibt dieser zugewiesene Typ T am Leben, bis sich der Timer zum ersten Mal nicht selbst erneuert, oder nach dem ersten Aufruf der Funktion, dass der T den Gültigkeitsbereich verlässt?Wann erlischt ein Asio-Timer?
Antwort
Ich habe keine Erfahrung mit Asio-Timern. Aber wenn Sie tun
void somefunc(void)
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
}
Dann ist der Timer außerhalb des Umfangs, wenn es die Funktion verlassen. Also mit diesem Code warte niemals. Wenn Sie t.wait() zu diesem Code hinzufügen, wartet es 5 Sekunden und beendet die Funktion und der Timer ist außerhalb des Gültigkeitsbereichs.
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();
}
Im zweiten Beispiel geht der Timer beim Beenden der Funktion aus dem Gültigkeitsbereich.
Wenn Sie den Timer umlaufen möchten, denke ich, dass Sie so schreiben müssen.
Das hält den Timer für eine Runde in der Schleife auf dem Stapel, und dann wird es neu erstellt. Wenn Sie den Timer außerhalb der Schleife platzieren, wird er nie außer Reichweite gesetzt. Aber dann musst du es in irgendeiner Weise zurücksetzen. Aber ich sehe keine solche Funktion.
BEARBEITEN: Im Beispiel von async_wait() wird der Timer zerstört, außerhalb des Bereichs, direkt ohne Ende, wenn Sie nicht die io.run() haben, um es warten zu lassen. Und ich würde vermuten, dass der Desuctor von deadline_timer() einen Abbruch des Timers durchführt, wenn er den Destruktor trifft.
Wenn Sie eine Funktion schreiben, in der Sie einen Timer auf dem Stack erstellen, dann rufen Sie async_wait auf, der Timer wird am Ende des Funktionsaufrufs zerstört und der Callback wird sofort mit dem richtigen Fehlerparameter aufgerufen.
Sie können das Timer-Objekt nicht mit boost :: bind an den Callback übergeben, da das Objekt nicht kopierbar ist.
Trotzdem können Sie Ihre Sammelmappe auf dem Heap verwalten und bei jedem Aufruf von async_wait einen gemeinsamen Zeiger übergeben. Dies könnte wie folgt aussehen:
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
}
Aktueller Code bitte? :) – vladr
Wäre nett, wenn du besser erklären könntest, wie du async_wait() benutzen willst. Vielleicht durch einen Code oder Metacode. Sie müssen möglicherweise wie in small_ducks antworten und erstellen Sie den Timer mit neuen, um es an andere Funktionen zu übergeben und den gewünschten Effekt zu erhalten. – jpyllman