Timer.3 - Binding arguments to a handler
In this tutorial we will modify the program from tutorial Timer.2 so that the timer fires once a second. This will show how to pass additional parameters to your handler function.
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
To implement a repeating timer using asio you need to change the timer's expiry time in your callback function, and to then start a new asynchronous wait. Obviously this means that the callback function will need to be able to access the timer object. To this end we add two new parameters to the print
function:
- A pointer to a timer object.
- A counter so that we can stop the program when the timer fires for the sixth time.
void print(const boost::system::error_code& /*e*/,
boost::asio::deadline_timer* t, int* count)
{
As mentioned above, this tutorial program uses a counter to stop running when the timer fires for the sixth time. However you will observe that there is no explicit call to ask the io_service to stop. Recall that in tutorial Timer.2 we learnt that the boost::asio::io_service::run() function completes when there is no more "work" to do. By not starting a new asynchronous wait on the timer when count
reaches 5, the io_service will run out of work and stop running.
if (*count < 5)
{
std::cout << *count << "\n";
++(*count);
Next we move the expiry time for the timer along by one second from the previous expiry time. By calculating the new expiry time relative to the old, we can ensure that the timer does not drift away from the whole-second mark due to any delays in processing the handler.
t->expires_at(t->expires_at() + boost::posix_time::seconds(1));
Then we start a new asynchronous wait on the timer. As you can see, the boost::bind() function is used to associate the extra parameters with your callback handler. The boost::asio::deadline_timer::async_wait() function expects a handler function (or function object) with the signature void(const boost::system::error_code&)
. Binding the additional parameters converts your print
function into a function object that matches the signature correctly.
See the Boost.Bind documentation for more information on how to use boost::bind().
In this example, the boost::asio::placeholders::error argument to boost::bind() is a named placeholder for the error object passed to the handler. When initiating the asynchronous operation, and if using boost::bind(), you must specify only the arguments that match the handler's parameter list. In tutorial Timer.4 you will see that this placeholder may be elided if the parameter is not needed by the callback handler.
t->async_wait(boost::bind(print,
boost::asio::placeholders::error, t, count));
}
}
int main()
{
boost::asio::io_service io;
A new count
variable is added so that we can stop the program when the timer fires for the sixth time.
int count = 0;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(1));
As in Step 4, when making the call to boost::asio::deadline_timer::async_wait() from main
we bind the additional parameters needed for the print
function.
t.async_wait(boost::bind(print,
boost::asio::placeholders::error, &t, &count));
io.run();
Finally, just to prove that the count
variable was being used in the print
handler function, we will print out its new value.
std::cout << "Final count is " << count << "\n";
return 0;
}
See the full source listing
Return to the tutorial index
Previous: Timer.2 - Using a timer asynchronously
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人