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

Next: Timer.4 - Using a member function as a handler

时间: 2024-10-12 19:35:03

Timer.3 - Binding arguments to a handler的相关文章

Timer.4 - Using a member function as a handler

In this tutorial we will see how to use a class member function as a callback handler. The program should execute identically to the tutorial program from tutorial Timer.3. #include <iostream> #include <boost/asio.hpp> #include <boost/bind.

Boost.Asio技术文档

Christopher Kohlhoff Copyright ? 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_0.txt文件或从http://www.boost.org/LICENSE_1_0.txt) Boost.Asio是用于网络和低层IO编程的跨平台C++库,为开发者提供了C++环境下稳定的异步模型. 综述 基本原理 应用程序与外界交互的方式有很多,可通过文件,网络,串口或控制台.例如在网络通信中,完

boost::asio译文

Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_0.txt文件或从http://www.boost.org/LICENSE_1_0.txt) Boost.Asio是用于网络和低层IO编程的跨平台C++库,为开发者提供了C++环境下稳定的异步模型. 综述 基本原理 应用程序与外界交互的方式有很多,可通过文件,网络,串口或控制台.例如在网络通信中,完

Android Handler Timer TimerTask组合实现定时刷新UI

代码实现一个小计时器 类似 00 : 01 : 00 的格式 import java.util.Timer; import java.util.TimerTask; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.TextView; public class MainActivity

android Handler vs Timer

Handler vs Timer 在我们Android开发过程中,经常需要执行一些短周期的定时任务,这时候有两个选择Timer或者Handler.然而个人认为: Handler 在多个方面比Timer更为优秀,更推荐使用. 一.易用性 可重复执行 Handler可以重复执行某个任务. Timer若在某个任务执行/取消之后,再次执行则会抛出一个IllegalStateException异常.为了避免这个异常,需要重新创建一个Timer对象. 周期可调整 若想要执行一个越来越快的定时任务,Handl

Handler机制原理图、源码、使用!!!!!

android的消息处理机制——Looper,Handler,Message  (原理图.源码) 转自:http://my.oschina.net/u/1391648/blog/282892 在开始讨论android的消息处理机制前,先来谈谈一些基本相关的术语. 通信的同步(Synchronous):指向客户端发送请求后,必须要在服务端有回应后客户端才继续发送其它的请求,所以这时所有请求将会在服务端得到同步,直到服务端返回请求.  通信的异步(Asynchronous):指客户端在发送请求后,不

Android之Handler用法总结

方法一:(java习惯,在android平台开发时这样是不行的,因为它违背了单线程模型) 刚刚开始接触android线程编程的时候,习惯好像java一样,试图用下面的代码解决问题 new Thread( new Runnable() { public void run() { myView.invalidate(); } }).start(); 可以实现功能,刷新UI界面.但是这样是不行的,因为它违背了单线程模型:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行. 方法二

Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等

方法一:(java习惯,在android不推荐使用) 刚刚开始接触android线程编程的时候,习惯好像java一样,试图用下面的代码解决问题 new Thread( new Runnable() { public void run() { myView.invalidate(); } }).start(); 可以实现功能,刷新UI界面.但是这样是不行的,因为它违背了单线程模型:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行. 方法二:(Thread+Handler)

Handler的总结

我们创建的Service.Activity,Broadcast均是一个主线程处理,即UI线程, 但是进行耗时操作时,比如I/O读写的大文件,数据库操作及网络下载需要很长的时间,为了不阻塞用户界面,出现ANR的响应提示窗口,我们可以考虑使用Thread线程来解决 1.对于线程中的刷新一个view为基类的界面,可以使用postInvalidate()方法在线程中处理,其中还提供了一些重写方法比如postInvalidate(int left,int top,int right,int bottom)