【C#】 定时器设计过程的记录

在Windows 系统上 C# 常用定时器有三种,而最高进度的定时器误差 58ms 则个误差数字无法应用 16ms 级别的定时轮询,但还有另外的高精度定时器,这不是还有其他方法吗,对有的,空转也指的是直接让线程一只空转,设置休眠线程的间隔来达到同样的目的,但这样就无法在休眠的时间内执行其他事情,弊端还很多;
另外的方式,也有框架实现的,误差虽然有很高的降低,但现在的机器要么很贵,要么误差要手动调整,增加了设计难度(本身这个设计就很复杂了,再加入精度与任务并发的平衡,工程有多大,新手几乎都得凉,这还整么有动力继续搞下去,前方好黑,笑容逐渐消失,脚步逐渐停止);
那么方法还是有的,使用多媒体定时器(winmm.dll),可实现精度 1ms ,看过大部分测试实例,时间间歇在 5ms最为稳定,具体使用方式还需自行百度等查询,毕竟这些资料很多,C#中用的:[DllImport(“winmm.dll”)] 方式。
在 5ms这么高的频率和精度,整么执行更多的任务,这就是设计的重点,另外还会介绍一种非高精度的常规定时器,适用什么时候有任务就什么时候执行,而非高精度定时器那样,不管有没有任务,我就要以这么高的频率同步转发数据。

一、高精度定时器

首先看高精度定时器执行队列设计模型,一个定时器能执行多个子任务,可同时存在多个定时器,这样实现更多的并发处理的数量,许多场景需要的同步频率需要注意,有些频率可能在 25帧,客户端对应的也是 1秒发送25帧 数据,同时接收25帧 返回的数据;这样就达到了一个压力与效率平衡的效果,有些框架设计会支持更多的频率来接收和发送,这只是消息框架的一种(可以再进行查阅质料),继续以 5ms 频率,可以把定时器执行看作一条由箭头的线条,而每隔 5ms 就执行一个子任务当作线条上平均分布的点,可看下图:

这样看,很明白就看出执行顺序,那么任务的实际频率是 25 帧 ,这如何实现呢?,继续向下看,既然任务是 25帧,1000ms中 25帧的间隔就是 40ms ,再看一个例子,如果任务是 20帧,那么间隔就是 50ms ,看到这些帧数间隔都是 5 的倍数,我们为其中一个帧数制定一个分组,也就是一个高精度定时器,配置一个轮询的值,这个值指示当前组内的第几个,如果以 25帧为例,那么间隔就是 40ms,在这 40ms间隔中,高精度定时器以每 5ms的速率执行了 8 个子任务,按照这个任务数字,将 8个任务交给一个高精度定时器处理,通过配置的轮询值记作下标,8 个任务在同一个数组(列表)中,通过每次调用 +1 ,并在下标值达到子任务数时,让下标重置为 0的方式,执行下标对应的子任务,这样,高精度定时器执行的代码就明确了,只需要每 5ms频率对下标值 +1 并执行下标对应的任务,高精度定时器的模型设计就完成了。如下图:

上面的模型适用精度高,同步效率高的应用,此模型纯属个人研究使用,如有疏漏还请原谅。

二、自动间隔定时器

下面继续另一种定时器设计,适用有任务才执行,没任务不执行,且不会空转消耗多余的性能,当我们有这样的需求功能:有个系统需要在 2s 执行发送消息任务,这样简单设置设置定时就可以了;等等,问题还没完,这只是一种 ,如果一个系统又有,更高频率的任务如:1s 或是频率更低的 5s 甚至 10s 的;还没完,后面又扩了一个模块的功能需要 3s 的任务。。。,我天,拿来这么多无厘头,这时候,系统中如果没有好好规划定时器的使用,越来越多的定时器同时运行,必定会又一个问题,在某时某刻多个定时器同时执行回调任务,包括空转调用,系统会经常的卡顿,这时基于可延时框架设计的定时器,偏差时间会越来越大。

这种多时段,多频率混合且精度在 1s内的任务需要执行,我想到用 AutoResetEvent + System.Threading.Timer 组合实现上面的要求,并去掉不必要的空转。
可变任务队列自动间隔任务执行模型,自动计算下一次执行的时间,在指定时间执行指定任务,多个任务自动合并(这个看具体实现了,模型只提供大概逻辑),具体设计:在定时器创建时,检查到任务队列为空,主循环使用AutoResetEvent进入任务等待,而定时器的执行逻辑只有一个作用,那就是发送AutoResetEvent信号,此外别无他用,当第一个定时任务插入队列时,任务队列为空,便设置定时器为任务要需要执行的时间,且任务可设置其他参数控制当前任务是否循环执行,或者执行次数(这需要一个存储任务与任务参数的对象),定时器时间到达时发送AutoResetEvent信号,主循环AutoResetEvent等待信号接收到时,执行任务队列首位的任务,执行完任务后,设置任务队列下一个任务为任务队列的首位,并更具新的首位的定时参数,重置定时器定时时间,当新的任务插入到队列时,更具执行时间排序,若新插入的任务定时时间,小于定时器定时的时间(定时器定时时间-已过去的时间<插入任务的时间)时,就将定时器重置为新插入任务的定时时间,并设置任务队列首位为当前新插如任务,如此循环往复。

定时器轮询模型的两种设计已经讲解完毕,资料方面确实没有准备,只能动手自己查阅了。

如有误导请联系,我会进行修正。
邮箱 hbck_gwx@qq.com

C# 定时器轮询 设计思路相关推荐

  1. python 定时器 ms_python 定时器,轮询定时器的示例

    python 定时器默认定时器只执行一次,第一个参数单位S,几秒后执行 import threading def fun_timer(): print('Hello Timer!') timer = ...

  2. ESP32 + ESP-IDF |GPIO 03 - 定时器轮询按钮的状态,控制LED亮或者灭

    一.前言 前面两个章节使用了GPIO的输出功能,本章节介绍如何使用ESP32上GPIO的输入功能. 通过一个简单的实验来学习这个功能: 1.开启一个定时器(上一章节学习了),定时器以每100ms的周期 ...

  3. Vue定时器轮询 及 销毁定时器

    项目中我们经常需要实现轮询 每隔几秒请求一次接口刷新数据 一般都会使用setInterval,但要注意单纯使用它可能导致页面卡死 原因是setInterval不会清除定时器队列,每重复执行1次都会导致 ...

  4. js setInterval+setTimeout定时器轮询+终止轮询

    常见的轮询方式: window.timer = setInterval(()=>{this.promiseFun()},1000) 大家一般都会使用setInterval,但要注意单纯使用它可能 ...

  5. SAP CRM呼叫中心和Hybris Backoffice的轮询设计

    在CRM的呼叫中心里,每隔1秒会有一个poll: the browser polls at regular intervals (typically once per second) to the s ...

  6. SAP CRM呼叫中心和Hybris Commerce Backoffice的轮询设计

    在CRM 呼叫中心还没有用ABAP push channel 重新设计之前,因为后台没法向浏览器push event,因此前台只能每隔1秒向后台发一个http request去询问后台是否有event ...

  7. 实现一个简单的长轮询

    分析一下长轮询的实现方式 现在各大中间件都使用了长轮询的数据交互方式,目前比较流行的例如Nacos的配置中心,RocketMQ Pull(拉模式)消息等,它们都是采用了长轮询方的式实现.就例如Naco ...

  8. 用了这么久配置中心,还不知道长轮询是什么?

    前言 传统的静态配置方式想要修改某个配置时,必须重新启动一次应用,如果是数据库连接串的变更,那可能还容易接受一些,但如果变更的是一些运行时实时感知的配置,如某个功能项的开关,重启应用就显得有点大动干戈 ...

  9. 负载均衡算法 — 轮询

    负载均衡算法 - 轮询 目录 概述 简单轮询 加权轮询 平滑加权轮询 1. 概述 在分布式系统中,为了实现负载均衡,必然会涉及到负载调度算法,如 Nginx 和 RPC 服务发现等场景.常见的负载均衡 ...

最新文章

  1. java 内存测试_请你说一下java jvm的内存机制
  2. 华为新版交换机端口配置由TRUNK改为ACCESS
  3. 解决SSH连接Linux超时自动断开
  4. Windows 技术篇-windows家庭版win+R运行搜不到gpedit.msc组策略编辑器解决方法,windows安装组策略编辑器方法
  5. c语言全角半角转换函数,全角半角转换函数(示例代码)
  6. Oracle Enterprise Manager打不开的解决方法
  7. 小米12 Ultra将搭载5倍潜望镜头:自研技术加持 成像相对更好
  8. 基于CUDA的离散傅里叶变换(Discrete Fourier Transform,DFT)
  9. 阿里AI获NLP顶会比赛冠军,达摩院计划推出首个通才型AI医生
  10. 《敏捷无敌》(8)之橄榄球与软件开发
  11. 无法解析的外部符号:GetWindowThreadProcessId/EnumWindow
  12. url后面的参数是什么_揭秘亚马逊黑科技之超级URL原理
  13. #高等数学# 第八章 微分方程
  14. 光能手写板 android,一种液晶光能手写板的制作方法
  15. kaggle Notebook Threw Exception问题解决
  16. 对比学习(contrastive learning)
  17. 曾仕强:领导最在乎什么?
  18. Tensorflow 笔记 Ⅺ——NLP 实现电影评论情感分析
  19. 公网访问本地内网web服务器【内网穿透】
  20. 新手初学Java List 接口

热门文章

  1. unity创建 《找不同》游戏 图片编辑器
  2. python语言单词_python单词_python 单词_python单词书 - 云+社区 - 腾讯云
  3. 上海出差之行--领略外滩美景、RT-Thread总部之旅、嵌友面基、返程记录
  4. python——基础题
  5. java和以太坊交互_Android怎么和以太坊智能合约交互
  6. virtualbox kali linux 安装小米随身wifi
  7. Mac 使用Charles后,退出Charles后,不能浏览网页,提示:未连接到互联网代理服务器出现问题,或者地址有误。
  8. 短域名服务设计与实现
  9. WAP 构建 Java 应用 和 WAP经验总结
  10. mysql常用的tamper脚本,Sqlmap Tamper绕过脚本详解