#include <x/threads/timer.H> x::timer bTimer(x::timer::create()); bTimer->setTimerName("background-task");
An
x::timer
is a
reference-counted object that
starts an on-demand thread that
executes run
() methods defined in
x::timertaskObj
objects:
#include <x/threads/timertask.H> class myTaskObj : public x::timertaskObj { // ... public: myTaskObj() noexcept {} ~myTaskObj() {} void run(); }; typedef x::ptr<myTaskObj> myTask; myTask newTask(myTask::create()); bTimer->schedule(newTask, std::chrono::system_clock::now()+std::chrono::seconds(2));
The tasks get executed in a separate execution thread.
Each task gets executed once, or repeatedly, at predetermined
intervals, until it's cancelled.
One
execution thread is associated with each
x::timer
object. It is not necessary to subclass
x::timer
and override its
getName()
method to set the execution thread's
name for logging purposes. Instead, invoke
setTimerName
() before adding the first task to the
timer object.
In this example,
myTaskObj
's run
() method
gets executed in two
seconds. Other schedule
()
methods are available which schedule
the task in various ways, including repeated executions at pretedermined
intervals, until the task get cancelled:
newTask->cancel();
A task's run
() may invoke its own
cancel
().
The cancellation takes
effect when the task's run
() method returns.
Multiple x::timertaskObj
instances can be
scheduled with the same
x::timer
.
Each
x::timer
runs a single execution thread.
While the thread is executing a
x::timertaskObj
's run
() method, all
other pending
x::timertaskObj
objects wait until the
current object's run
() method terminates.
This timer object is not suitable for long running tasks.
The timer thread holds a strong reference on each task object that's pending execution. In the case of a one-time task, the thread releases its reference on the task object after executing it, or until it gets cancelled. In the case of a repeated task, the thread releases its reference on the task object after it gets cancelled.
x::timertask::base::make_timer_task
() constructs a subclass of
x::timertaskObj
from a functor:
bTimer->schedule(x::timertask::base::make_timer_task([] { dosomething(); }), std::chrono::system_clock::now()+std::chrono::seconds(2));
make_timer_task
takes a reference to a
functor, and returns a reference to an instantiated subclass of a
x::timertaskObj
whose
run
() invokes the functor.
The functor takes no arguments, but it can use captured objects. Except under very controlled circumstances, the functor should capture by value, since the functor ends up getting executed by a different thread.
Once scheduled, the timer thread holds a strong reference on the timer task object, until the task is no longer scheduled. A recurring task must be explicitly cancelled.
x::timertaskObj
's
autocancel
() method returns a mcguffin
whose destructor invokes cancel
() on the
timer task. When the mcguffin goes out of scope and gets destroyed,
this results in the task's automatic cancellation.
This also applies to task objects created by
x::timertask::base::make_timer_task
(),
since they subclass
x::timertaskObj
:
auto doSomethingTask=x::timertask::base::make_timer_task([] { dosomething(); }); x::ref<x::obj> mcguffin=doSomethingTask->autocancel(); bTimer->scheduleAtFixedRate(doSomethingTask, std::chrono::seconds(30));
When this mcguffin goes out of scope and gets destroyed, the task's
cancel
() method gets invoked, to cancel it.