### Timer.2 - Using a timer asynchronously

This tutorial program demonstrates how to use asio's asynchronous callback functionality by modifying the program from tutorial Timer.1 to perform an asynchronous wait on the timer.

    #include <iostream>
    #include <asio.hpp>

Using asio's asynchronous functionality means having a callback function that will be called when an asynchronous operation completes. In this program we define a function called `print` to be called when the asynchronous wait finishes.

    void print(const asio::error_code& /*e*/)
    {
      std::cout << "Hello, world!" << std::endl;
    }

    int main()
    {
      asio::io_context io;

      asio::steady_timer t(io, asio::chrono::seconds(5));

Next, instead of doing a blocking wait as in tutorial Timer.1, we call the steady_timer::async_wait() function to perform an asynchronous wait. When calling this function we pass the `print` callback handler that was defined above.

      t.async_wait(&print);

Finally, we must call the io_context::run() member function on the io_context object.

The asio library provides a guarantee that callback handlers will only be called from threads that are currently calling io_context::run(). Therefore unless the io_context::run() function is called the callback for the asynchronous wait completion will never be invoked.

The io_context::run() function will also continue to run while there is still "work" to do. In this example, the work is the asynchronous wait on the timer, so the call will not return until the timer has expired and the callback has completed.

It is important to remember to give the io_context some work to do before calling io_context::run(). For example, if we had omitted the above call to steady_timer::async_wait(), the io_context would not have had any work to do, and consequently io_context::run() would have returned immediately.

      io.run();

      return 0;
    }

See the full source listing

Return to the tutorial index

Previous: Timer.1 - Using a timer synchronously

Next: Timer.3 - Binding arguments to a handler