避免定时器在复杂的任务中被反复启动的小技巧

我们有时希望设计这样的程序,周期性的访问ftp服务器执行一些文件查询或下载,有时有的ftp服务器网络很好,速度很快,有时有的服务器网络较差,访问较慢,也就是说,查询或下载时间并不稳定,如果把定时器的时间指定为一个固定值,较大的值,时间浪费较多,较小的值,有时没查询完,定时器就启动下一次查询,解决办法也许较多,这里介绍一个非常好的解决办法,很实用,定时器选System.Threading空间下的Timer,在执行后台任务时,这个是最好用的定时器,把period参数设置为TimeOut.Infinite,这时定时器Timer只执行一次,然后在回调方法中,当完成大量复杂任务后,再设置Change方法,把dueTime设置要间隔的时间,把period再次设置为TimeOut.Infinite值,这样定时器再次被设置为执行一次,如此反复。代码见下:

class Program
    {
        private static Timer timer;
        private static CancellationTokenSource cts;
        static void Main(string[] args)
        {
            cts = new CancellationTokenSource();
            timer = new Timer(DoWork, cts, Timeout.Infinite, Timeout.Infinite);
            timer.Change(0, Timeout.Infinite);

            Console.WriteLin
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Strand 可以使用 Boost.Asio 库的定时器功能来实现延迟执行任务的效果。具体步骤如下: 首先,在 Strand 对象创建一个 boost::asio::deadline_timer 对象,这个对象可以用来设置定时器的超时时间,并在超时时触发回调函数。在创建定时器对象时,需要指定定时器所使用的 IO 对象(即 I/O 上下文)和 Strand 对象。 然后,在任务队列加入要延迟执行的任务。在任务,使用定时器对象的 async_wait 函数来启动定时器。async_wait 函数会阻塞当前任务,直到定时器超时或被取消。 最后,在定时器超时时触发的回调函数,将延迟执行的任务任务队列取出,放到 Strand 执行即可。 下面是一个简单的示例代码: ``` #include <boost/asio.hpp> #include <boost/asio/strand.hpp> #include <iostream> using namespace boost::asio; class MyTask { public: MyTask(io_context& io, strand<io_context::executor_type>& strand) : io_(io), strand_(strand) {} void run() { // 将要延迟执行的任务加入任务队列 strand_.post([this]() { std::cout << "Task start" << std::endl; // 创建定时器对象 deadline_.expires_from_now(boost::posix_time::seconds(3)); // 启动定时器,阻塞当前任务 deadline_.async_wait([this](const boost::system::error_code& ec) { if (!ec) { // 定时器超时,执行任务 std::cout << "Task done" << std::endl; } }); }); } private: io_context& io_; strand<io_context::executor_type>& strand_; deadline_timer deadline_{ io_ }; }; int main() { io_context io; strand<io_context::executor_type> strand{ io.get_executor() }; MyTask task{ io, strand }; task.run(); io.run(); } ``` 在上面的代码,MyTask 类代表要延迟执行的任务。run 函数,先将任务加入 Strand 。然后,在 Strand 的回调函数,创建定时器对象,并启动定时器。当定时器超时时,触发回调函数,将要延迟执行的任务任务队列取出,放到 Strand 执行。 注意,在执行 io.run() 之前,需要将任务加入任务队列。这样,当 io.run() 启动 IO 线程时,任务队列已经有任务可以执行了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值