GVKun编程网logo

C ++ Boost ASIO简单的定期计时器?(c++定时器使用)

16

在这里,我们将给大家分享关于C++BoostASIO简单的定期计时器?的知识,让您更了解c++定时器使用的本质,同时也会涉及到如何更有效地android–如何停止尚未完成的计时器然后启动一个新计时器?

在这里,我们将给大家分享关于C ++ Boost ASIO简单的定期计时器?的知识,让您更了解c++定时器使用的本质,同时也会涉及到如何更有效地android – 如何停止尚未完成的计时器然后启动一个新计时器?、android – 如何在ListView中处理多个倒计时计时器?、android-如何取消计时器并更新相同的计时器?、boost------asio 库的使用 1 (Boost 程序库完全开发指南) 读书笔记的内容。

本文目录一览:

C ++ Boost ASIO简单的定期计时器?(c++定时器使用)

C ++ Boost ASIO简单的定期计时器?(c++定时器使用)

我希望一个非常简单的定期计时器每50毫秒调用一次我的代码。我可以使一个线程一直保持50ms的睡眠时间(但这很痛苦)……我可以开始研究Linux
API来制作定时器(但它不是可移植的)……

使用boost。我只是不知道这是可能的。Boost是否提供此功能?

答案1

小编典典

Boosts Asio教程中的第二个示例对此进行了解释。
你可以在这里找到它。

之后,请查看第三个示例,以了解如何以周期性的时间间隔再次调用它

android – 如何停止尚未完成的计时器然后启动一个新计时器?

android – 如何停止尚未完成的计时器然后启动一个新计时器?

我正在尝试做各种各样的猜谜游戏.问题是我的计时器在回答问题(按下按钮)并启动新计时器后流入下一个计时器.这导致两个定时器以不同的间隔改变文本视图,这不是它应该如何.我想知道如何停止我之前的倒计时并开始一个新的倒计时.谢谢!这是我的代码:

button.setonClickListener(new View.OnClickListener() {
public void onClick(View v) {
 final TextView textic = (TextView) findViewById(R.id.button1);
                                long total = 30000;
            final CountDownTimer Count = new CountDownTimer(total, 1000) {

                public void onTick(long millisUntilFinished) {
                    textic.setText("Time Left: " + millisUntilFinished / 1000);
                }
                public void onFinish() {
                    textic.setText("OUT OF TIME!");
                    finish();
                }
                }; 
                Count.start();

解决方法:

我没有测试代码,但我会使用这样的东西:

 final TextView textic = (TextView) findViewById(R.id.button1);
 final android.os.CountDownTimer Count = new android.os.CountDownTimer(total, 1000) {
       public void onTick(long millisUntilFinished) {
           textic.setText("Time Left: " + millisUntilFinished / 1000);
       }
       public void onFinish() {
           textic.setText("OUT OF TIME!");
       }
 }; 
 button.setonClickListener(new View.OnClickListener() {
      public void onClick(View v) {
          Count.cancel();
          Count.start();
      }
   });

android – 如何在ListView中处理多个倒计时计时器?

android – 如何在ListView中处理多个倒计时计时器?

我有一个listview(使用自定义列表适配器),我需要在每一行显示倒计时.

例如,如果我的列表包含4个项目,我将有4行.
在这一点上,我需要处理4个不同的倒计时(每行一个),因为时间不同.

到目前为止,我使用以下方式处理它:在自定义列表适配器中,在getView()方法内部,我创建一个新的CountDownTimer,并在TextView中显示剩余时间.

但是问题是它减慢了很多活动,甚至在最坏的情况下甚至无法正确滚动(因为每次显示一行,都会创建一个新的CountDownTimer).

我搜索了很多更好的解决方案,但没有人满意.

有没有更清洁和更平滑的解决方案来处理listView中的多个倒计时计时器?

谢谢

解决方法

而不是试图显示所有的剩余时间,这个想法是更新可见项目的剩余时间.

请按照以下示例代码,让我知道:

主要活动 :

public class MainActivity extends Activity {

private ListView lvItems;
private List<Product> lstProducts;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    lvItems = (ListView) findViewById(R.id.lvItems);
    lstProducts = new ArrayList<>();
    lstProducts.add(new Product("A",System.currentTimeMillis() + 10000));
    lstProducts.add(new Product("B",System.currentTimeMillis() + 20000));
    lstProducts.add(new Product("C",System.currentTimeMillis() + 20000));
    lstProducts.add(new Product("D",System.currentTimeMillis() + 20000));
    lstProducts.add(new Product("E",System.currentTimeMillis() + 20000));
    lstProducts.add(new Product("F",System.currentTimeMillis() + 20000));
    lstProducts.add(new Product("G",System.currentTimeMillis() + 30000));
    lstProducts.add(new Product("H",System.currentTimeMillis() + 20000));
    lstProducts.add(new Product("I",System.currentTimeMillis() + 20000));
    lstProducts.add(new Product("J",System.currentTimeMillis() + 40000));
    lstProducts.add(new Product("K",System.currentTimeMillis() + 20000));
    lstProducts.add(new Product("L",System.currentTimeMillis() + 50000));
    lstProducts.add(new Product("M",System.currentTimeMillis() + 60000));
    lstProducts.add(new Product("N",System.currentTimeMillis() + 20000));
    lstProducts.add(new Product("O",System.currentTimeMillis() + 10000));

    lvItems.setAdapter(new CountdownAdapter(MainActivity.this,lstProducts));
}

private class Product {
    String name;
    long expirationTime;

    public Product(String name,long expirationTime) {
        this.name = name;
        this.expirationTime = expirationTime;
    }
}


public class CountdownAdapter extends ArrayAdapter<Product> {

    private LayoutInflater lf;
    private List<ViewHolder> lstHolders;
    private Handler mHandler = new Handler();
    private Runnable updateRemainingTimeRunnable = new Runnable() {
        @Override
        public void run() {
            synchronized (lstHolders) {
                long currentTime = System.currentTimeMillis();
                for (ViewHolder holder : lstHolders) {
                    holder.updateTimeRemaining(currentTime);
                }
            }
        }
    };

    public CountdownAdapter(Context context,List<Product> objects) {
        super(context,objects);
        lf = LayoutInflater.from(context);
        lstHolders = new ArrayList<>();
        startUpdateTimer();
    }

    private void startUpdateTimer() {
        Timer tmr = new Timer();
        tmr.schedule(new TimerTask() {
            @Override
            public void run() {
                mHandler.post(updateRemainingTimeRunnable);
            }
        },1000,1000);
    }

    @Override
    public View getView(int position,View convertView,ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            holder = new ViewHolder();
            convertView = lf.inflate(R.layout.list_item,parent,false);
            holder.tvProduct = (TextView) convertView.findViewById(R.id.tvProduct);
            holder.tvTimeRemaining = (TextView) convertView.findViewById(R.id.tvTimeRemaining);
            convertView.setTag(holder);
            synchronized (lstHolders) {
                lstHolders.add(holder);
            }
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.setData(getItem(position));

        return convertView;
    }
}

private class ViewHolder {
    TextView tvProduct;
    TextView tvTimeRemaining;
    Product mProduct;

    public void setData(Product item) {
        mProduct = item;
        tvProduct.setText(item.name);
        updateTimeRemaining(System.currentTimeMillis());
    }

    public void updateTimeRemaining(long currentTime) {
        long timeDiff = mProduct.expirationTime - currentTime;
        if (timeDiff > 0) {
            int seconds = (int) (timeDiff / 1000) % 60;
            int minutes = (int) ((timeDiff / (1000 * 60)) % 60);
            int hours = (int) ((timeDiff / (1000 * 60 * 60)) % 24);
            tvTimeRemaining.setText(hours + " hrs " + minutes + " mins " + seconds + " sec");
        } else {
            tvTimeRemaining.setText("Expired!!");
        }
    }
}
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ListView
    android:id="@+id/lvItems"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

</RelativeLayout>

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp">

<TextView
    android:id="@+id/tvProduct"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:text="Product Name"
    android:textSize="16dp"
    android:text/>

<TextView
    android:id="@+id/tvTimeRemaining"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:text="Time Remaining : " />

</LinearLayout>

android-如何取消计时器并更新相同的计时器?

android-如何取消计时器并更新相同的计时器?

我正在创建一个每30秒振动和发出蜂鸣声的应用程序,当我注销振动和发出蜂鸣声时必须取消,并且在登录振动并发出蜂鸣声时应该恢复.

注意:它必须每30秒振动并发出蜂鸣声,直到我注销为止

在我的应用中,我正在使用TimerTask进行此实现

这是使用TimerTask振动和发出蜂鸣声的代码

static TimerTask Task;
final static Handler handler = new Handler();
static Timer t = new Timer();

public static void vib() {

    Task = new TimerTask() {
        public void run() {
            handler.post(new Runnable() {
                public void run() {
                    Vibrator vibrator = (Vibrator) ApplicationUtils.getContext().getSystemService(Context.VIBRATOR_SERVICE);
                    vibrator.vibrate(3000);
                    playSound();
                    Log.d("TIMER", "Timer set on");
                }
            });
        }
    };
    t.schedule(Task, 0, 30000); 
}

这是我在注销部分中使用的代码

public void stopvib() {
    if (Task != null) {
    //  Log.d("TIMER", "timer canceled");
        t.cancel();
        Task.cancel();
    }
}

注意:我也删除了Task.cancel();.但是我仍然遇到同样的错误

我的振动工作正常,然后注销并再次登录我遇到错误

java.lang.IllegalStateException: Timer was cancelled
    at java.util.Timer.scheduleImpl(Timer.java:562)
    at java.util.Timer.schedule(Timer.java:481)
    at com.vib(AlertListActivity.java:724)

谁能帮我这个编码.我哪里做错了?

解决方法:

我最近运行了此代码,并且工作正常.这可以使用广播Receiver来实现.您必须实现单独的CustomTimer任务来扩展TimerTask:

Activity mActivity=null;
public MyCustomTimer(Activity mActivity) {
    this.mActivity=mActivity;
}
    @Override
    public void run() {
        this.mActivity.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                Toast.makeText(mActivity, "Write you code here",Toast.LENGTH_LONG).show();
                Log.d("MyCustomTimer","Call");
            }
        });

    }

之后,您必须在要实现“ vib()”方法的类中实现broadCast Receive ::
可以说,就我而言(例如)是MainActivity:

public class MainActivity extends Activity {
    private MyCustomTimer myCustomTimer = null;
    broadcastReceiver mBr_Start = new broadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("START_VIBRATION")) {
                System.out.println("onreceive :START_VIBRATION");
                vib();
            }
        }
    };
    broadcastReceiver mBr_Stop = new broadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("STOP_VIBRATION")) {
                stopVibration();
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        IntentFilter mIntentFilter = new IntentFilter();
        mIntentFilter.addAction("START_VIBRATION");
        registerReceiver(mBr_Start, mIntentFilter);
        IntentFilter mIntentFilter2 = new IntentFilter();
        mIntentFilter2.addAction("STOP_VIBRATION");
        registerReceiver(mBr_Stop, mIntentFilter2);

        Button b1 = (Button) findViewById(R.id.button1);
        b1.setonClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent i = new Intent(MainActivity.this, MySecondActivity.class)
                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);

            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    private void vib() {
        myCustomTimer = new MyCustomTimer(MainActivity.this);
        Timer timer = new Timer();
        timer.scheduleAtFixedrate(myCustomTimer, 0, 30000);
    }

    private void stopVibration() {
        Log.d("MainActivity", "Before Cancel");
        if (null != myCustomTimer)
            myCustomTimer.cancel();
        Log.d("MainActivity", "After Cancel");
    }

}

现在,您可以通过实现以下几行来开始或停止振动:
开始振动:

Intent i=new Intent("START_VIBRATION");
                mActivity.sendbroadcast(i);

停止:

Intent i=new Intent("STOP_VIBRATION");
                mActivity.sendbroadcast(i);

注意:
MainActivity的onDestroy()(在您的情况下,在实现broadcast Receiver的地方,取消注册broadcastReceiver.)

boost------asio 库的使用 1 (Boost 程序库完全开发指南) 读书笔记

boost------asio 库的使用 1 (Boost 程序库完全开发指南) 读书笔记

asio 库基于操作系统提供的异步机制,采用前摄器设计模式 (Proactor) 实现了可移植的异步 (或者同步) IO 操作,而且并不要求多线程和锁定,有效地避免了多线程编程带来的诸多有害副作用。

 

目前 asio 主要关注于网络通信方面,使用大量的类和函数封装了 socket API,支持 TCP、TCMP、UDP 等网络通信协议。但 asio 的异步操作并不局限于网络编程,它还支持串口读写、定时器、SSL 等功能,而且 asio 是一个很好的富有弹性的框架,可以扩展到其他有异步操作需要的领域

 

 

概述

asio 库基于前摄器模式封装了操作系统的 select、poll/epoll、kqueue、overlapped I/O 等机制,实现了异步 IO 模型。它的核心类 io_service,相当于前摄器模式中的 Proactor 角色,asio 的任何操作都需要有 io_service 的参与。

 

在同步模式下,程序发起一个 IO 操作,向 io_service 提交请求,io_service 把操作转交给操作系统,同步地等待。当 IO 操作完成时,操作系统通知 io_service,然后 io_service 再把结果发回给程序,完成整个同步流程。这个处理流程与多线程的 join () 等待方式很相似。

 

在异步模式下,程序除了要发起的 IO 操作,还要定义一个用于回调的完成处理函数。io_service 同样把 IO 操作转交给操作系统执行,但它不同步等待,而是立即返回。调用 io_service 的 run () 成员函数可以等待异步操作完成,当异步操作完成时 io_service 从操作系统获取执行结果,调用完成处理函数。

 

asio 不直接使用操作系统提供的线程,而是定义了一个自己的线程概念:strand,它保证在多线程的环境中代码可以正确地执行,而无需使用互斥量。io_service::strand::wrap () 函数可以包装一个函数在 strand 中执行。

 

asio 库使用 system 库的 error_code 和 system_error 来表示程序运行的错误。

 

定时器

 

定时器是 asio 库里最简单的一个 IO 模型示范,提供等待时间终止的功能,通过它我们可以快速熟悉 asio 的基本使用方法:

同步定时器

 

[cpp] view plain copy

 print?在CODE上查看代码片派生到我的代码片

  1. #include "stdafx.h"  
  2. #include "boost/asio.hpp"  
  3. #include "boost/date_time/posix_time/posix_time.hpp"  
  4. #include "iostream"  
  5. using namespace std;  
  6.   
  7.   
  8. int _tmain(int argc, _TCHAR* argv[])  
  9. {  
  10.     boost::asio::io_service ios;    // 所以的 asio 程序必须要有一个 io_service 对象  
  11.   
  12.     // 定时器 io_service 作为构造函数参数,两秒钟之后定时器终止  
  13.     boost::asio::deadline_timer t(ios, boost::posix_time::seconds(2));  
  14.   
  15.     cout << t.expires_at() << endl; // 查看终止的绝对事件  
  16.   
  17.     t.wait();                       // 调用 wait 同步等待  
  18.     cout << "hello asio" << endl;  
  19.   
  20.     return 0;  
  21. }  

 

 

可以把它与 thread 库的 sleep () 函数对比研究一下,两者都是等待,但内部机制完成不同:thread 库的 sleep () 使用了互斥量和条件变量,在线程中等待,而 asio 则是调用了操作系统的异步机制,如 select、epoll 等完成的。

 

 

异步定时器

下面的是异步定时器,代码大致与同步定时器相等,增加了回调函数,并使用 io_service.run () 和定时器的 async_wait () 方法

[cpp] view plain copy

 print?在CODE上查看代码片派生到我的代码片

  1. #include "stdafx.h"  
  2. #include "boost/asio.hpp"  
  3. #include "boost/date_time/posix_time/posix_time.hpp"  
  4. #include "iostream"  
  5. using namespace std;  
  6.   
  7.   
  8. void Print(const boost::system::error_code& error)  
  9. {  
  10.     cout << "hello asio" << endl;  
  11. }  
  12.   
  13.   
  14. int _tmain(int argc, _TCHAR* argv[])  
  15. {  
  16.     boost::asio::io_service ios;    // 所以的 asio 程序必须要有一个 io_service 对象  
  17.   
  18.     // 定时器 io_service 作为构造函数参数,两秒钟之后定时器终止  
  19.     boost::asio::deadline_timer t(ios, boost::posix_time::seconds(2));  
  20.   
  21.     t.async_wait(Print);                        // 调用 wait 异步等待  
  22.   
  23.     cout << "it show before t expired." << endl;  
  24.   
  25.     ios.run();  
  26.   
  27.     return 0;  
  28. }  

代码的前两行与同步定时器相同,这是所有 asio 程序基本的部分。重要的是异步等待 async_wait (),它通知 io_service 异步地执行 io 操作,并且注册了回调函数,用于在 io 操作完成时由事件多路分离器分派返回值 (error_code) 调用

 

最后必须调用 io_service 的 run () 成员函数,它启动前摄器的事件处理循环,阻塞等待所有的操作完成并分派事件。如果不调用 run () 那么虽然操作被异步执行了,但没有一个等待它完成的机制,回调函数将得不到执行机会。

 

 

异步定时器使用 bind

异步定时器中由于引入了回调函数,因此产生了很多的变化,可以增加回调函数的参数,使它能够做更多的事情。但 async_wait () 接受的回调函数类型是固定的,必须使用 bind 库来绑定参数以适配它的接口

   下面实现一个可以定时执行任意函数的定时器 AsynTimer (asyctimer),它持有一个 asio 定时器对象和一个计数器,还有一个 function 对象来保存回调函数

[cpp] view plain copy

 print?在CODE上查看代码片派生到我的代码片

  1. #include "stdafx.h"  
  2. #include "boost/asio.hpp"  
  3. #include "boost/date_time/posix_time/posix_time.hpp"  
  4. #include "boost/bind.hpp"  
  5. #include "boost/function.hpp"  
  6. #include "iostream"  
  7. using namespace std;  
  8.   
  9.   
  10. class AsynTimer  
  11. {  
  12. public:  
  13.     template<typename F>                              // 模板类型,可以接受任意可调用物  
  14.     AsynTimer(boost::asio::io_service& ios, int x, F func)  
  15.         :f(func), count_max(x), count(0),               // 初始化回调函数和计数器  
  16.         t(ios, boost::posix_time::millisec(500))        // 启动计时器  
  17.     {  
  18.         t.async_wait(boost::bind(&AsynTimer::CallBack,  // 异步等待计时器  
  19.             this, boost::asio::placeholders::error));   // 注册回调函数  
  20.     }  
  21.   
  22.     void CallBack(const boost::system::error_code& error)  
  23.     {  
  24.         if (count >= count_max)   // 如果计数器达到上限则返回  
  25.         {  
  26.             return;  
  27.         }  
  28.         ++count;  
  29.         f();                     // 调用 function 对象  
  30.   
  31.         // 设置定时器的终止时间为 0.5 秒之后  
  32.         t.expires_at(t.expires_at() + boost::posix_time::microsec(500));  
  33.         // 再次启动定时器,异步等待  
  34.         t.async_wait(boost::bind(&AsynTimer::CallBack, this, boost::asio::placeholders::error));  
  35.     }  
  36.   
  37. private:  
  38.     int count;  
  39.     int count_max;  
  40.     boost::function<void()> f;        // function 对象,持有无参无返回值的可调用物  
  41.     boost::asio::deadline_timer t;  // asio 定时器对象  
  42. };  
  43.   
  44. // 第一个回调函数  
  45. void print1()  
  46. {  
  47.     cout << "hello asio" << endl;  
  48. }  
  49.   
  50. // 第二个回调函数  
  51. void print2()  
  52. {  
  53.     cout << "hello boost" << endl;  
  54. }  
  55.   
  56.   
  57. int _tmain(int argc, _TCHAR* argv[])  
  58. {  
  59.     boost::asio::io_service ios;  
  60.   
  61.     AsynTimer t1(ios, 10, print1); // 启动第一个定时器  
  62.     AsynTimer t2(ios, 10, print2); // 启动第二个定时器  
  63.   
  64.     ios.run();  // io_service 等待异步调用结束  
  65.   
  66.     return 0;  
  67. }  

 

注意在 async_wait () 中 bind 的用法,CallBack 是 AsynTimer 的一个成员函数,因此需要绑定 this 指针,同时还使用了 asio 下子名字空间 placeholders 下的一个占位符 error,他的作业类似于 bind 库的占位符_1、_2,用于传递 error_code 值。

 

接下来是 AsynTimer 的主要功能函数 CallBack,它符合 async_wait () 对回调函数的要求,有一个 error_code 参数,当定时器终止时它将被调用执行

 

CallBack 函数内部累加器,如果计数器未达到上限则调用 function 对象 f,然后重新设置定时器的终止时间,再次异步等待被调用,从而达到反复执行的目的

今天关于C ++ Boost ASIO简单的定期计时器?c++定时器使用的介绍到此结束,谢谢您的阅读,有关android – 如何停止尚未完成的计时器然后启动一个新计时器?、android – 如何在ListView中处理多个倒计时计时器?、android-如何取消计时器并更新相同的计时器?、boost------asio 库的使用 1 (Boost 程序库完全开发指南) 读书笔记等更多相关知识的信息可以在本站进行查询。

本文标签: