C# 定时器轮询 设计思路

2023-11-05

【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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 定时器轮询 设计思路 的相关文章

  • 用于代数简化和求解的 C# 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 网络上有很多代数求解器和简化器 例如 algebra com 上不错的代数求解器和简化器 然而 我正在
  • 如何在c++中读取pcap文件来获取数据包信息?

    我想用 C 编写一个程序来读取 pcap 文件并获取数据包的信息 例如 len sourc ip flags 等 现在我找到了如下代码 我认为它会帮助我获取信息 但是我有一些疑问 首先我想知道应该将哪个库添加到我的程序中 然后什么是 pca
  • 确保 StreamReader 不会挂起等待数据

    下面的代码读取从 tcp 客户端流读取的所有内容 并且在下一次迭代中它将仅位于 Read 上 我假设正在等待数据 我如何确保它不会在没有任何内容可供读取时返回 我是否必须设置低超时 并在失败时响应异常 或者有更好的办法吗 TcpClient
  • 在 DataView 的 RowFilter 中选择 DISTINCT

    我试图根据与另一个表的关系缩小 DataView 中的行范围 我使用的 RowFilter 如下 dv new DataView myDS myTable id IN SELECT DISTINCT parentID FROM myOthe
  • 使用 LINQ2SQL 在 ASP.NET MVC 中的各种模型存储库之间共享数据上下文

    我的应用程序中有 2 个存储库 每个存储库都有自己的数据上下文对象 最终结果是我尝试将从一个存储库检索到的对象附加到从另一个存储库检索到的对象 这会导致异常 Use 构造函数注入将 DataContext 注入每个存储库 public cl
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 如何区分用户点击链接和页面自动重定向?

    拥有 C WebBrowser control http msdn microsoft com en us library system windows forms webbrowser aspx在我的 WinForms 应用程序中 并意识
  • 为什么 Google 测试会出现段错误?

    我是 Google Test 的新手 正在尝试提供的示例 我的问题是 当我引入失败并设置GTEST BREAK ON FAILURE 1 或使用命令行选项 GTest 将出现段错误 我正在考虑这个例子 https code google c
  • 回发后刷新时提示确认表单重新提交。我做错了什么?

    我有一个以空白 默认状态启动的仪表板 我让用户能够将保存的状态加载到仪表板中 当他们单击 应用 按钮时 我运行以下代码 function CloseAndSave var radUpload find radUpload1ID var in
  • 是否有实用的理由使用“if (0 == p)”而不是“if (!p)”?

    我倾向于使用逻辑非运算符来编写 if 语句 if p some code 我周围的一些人倾向于使用显式比较 因此代码如下所示 if FOO p some code 其中 FOO 是其中之一false FALSE 0 0 0 NULL etc
  • Azure 辅助角色“请求输入之一超出范围”的内部异常。

    我在辅助角色中调用 CloudTableClient CreateTableIfNotExist 方法 但收到一个异常 其中包含 请求输入之一超出范围 的内部异常 我做了一些研究 发现这是由于将表命名为非法表名引起的 但是 我尝试为我的表命
  • 为什么 std::strstream 被弃用?

    我最近发现std strstream已被弃用 取而代之的是std stringstream 我已经有一段时间没有使用它了 但它做了我当时需要做的事情 所以很惊讶听到它的弃用 我的问题是为什么做出这个决定 有什么好处std stringstr
  • 外键与独立关系 - Entity Framework 5 有改进吗?

    我读过了several http www ladislavmrnka com 2011 05 foreign key vs independent associations in ef 4 文章和问题 https stackoverflow
  • AES 128 CBC 蒙特卡罗测试

    我正在 AES 128 CBC 上执行 MCT 如中所述http csrc nist gov groups STM cavp documents aes AESAVS pdf http csrc nist gov groups STM ca
  • 使用管道时,如果子进程数量大于处理器数量,进程是否会被阻塞?

    当子进程数量很大时 我的程序停止运行 我不知道问题是什么 但我猜子进程在运行时以某种方式被阻止 下面是该程序的主要工作流程 void function int process num int i initial variables for
  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • 我的班级应该订阅自己的公共活动吗?

    我正在使用 C 3 0 遵循标准事件模式我有 public event EventHandler
  • Oracle Data Provider for .NET 不支持 Oracle 19.0.48.0.0

    我们刚刚升级到 Oracle 19c 19 3 0 所有应用程序都停止工作并出现以下错误消息 Oracle Data Provider for NET 不支持 Oracle 19 0 48 0 0 我将 Oracle ManagedData
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看

随机推荐

  • MySQL——流程控制函数

    在 MySQL 中 流程控制函数是指可以控制存储过程 stored procedure 或函数 function 中执行流程的语句 以下是几个常用的流程控制函数 1 IF函数 实现IF ELSE 的效果 如果expr1为true 则返回ex
  • arduino控制42步进电机——先动起来

    前言 好久之前就想分享出来 现在有点晚了 不过还是想简单的分享一下 在学校里一次做创新项目的机会 让我认识了步进电机 当时老师让我们用PLC发出脉冲的方式让步进电机动起来 可是我刚拿到步进电机时以为会像小马达一样 给正负直流电源就会跑 但是
  • c语言试卷自动批改系统.c

    一 题目要求 c语言试卷自动批改系统 1 answer txt为题目的答案文件 2 学生的答题信息用文件保存 即学号 txt 里面的内容为学生的答案 3 根据学号 txt与answer txt来判断学生答案是否正确来获取学生分数 每题五分
  • 火爆!用GPT接入midjounery绘图

    先看效果图吧 画了一只狗 gpt next web这个项目接入mj绘图 需要登录进入midjounery api网站后 复制一下api token key 3 网上找下GPT Next这个项目 建议电脑 手机有时候不显示图片 按照下方图示
  • 软件质量模型的六大特性和27个子特性

    软件质量模型的六大特性和27个子特性如下 ISO IEC9123软件质量特性 图示 一 功能性 1 适合性 解释软件产品是否提供了相应的功能 2 准确性 软件提供的功能是否正确 用户需要的 即解释软件对不对 3 互操作性 产品与产品之间交互
  • SQL优化(二):根据工具来SQL优化

    前一章节 讲的是explain的使用以及他结果的解析 实际上工具远远不止explain一个 还有慢查询 SHOW PROFILE这些 而且光读工具的说明书也不行 还要实际的根据工具返回的结果找到原因 根据实际情况是物理宿主机配置太低了要升级
  • Netty4详解三:Netty架构设计

    读完这一章 我们基本上可以了解到Netty所有重要的组件 对Netty有一个全面的认识 这对下一步深入学习Netty是十分重要的 而学完这一章 我们其实已经可以用Netty解决一些常规的问题了 一 先纵览一下Netty 看看Netty都有哪
  • 关于linux内核学习的误区以及相关书籍介绍

    第一篇 先说句正经的 其实我没资格写这篇文章 因为自己也就一两个月以来才开始有所领悟的 因此 这里与其说是关于linux内核学习的经验 不如说是自己的教训吧 希望不要扔鸡蛋砸我 常常有人问 我想学习内核 需要什么基础吗 linus torv
  • uni微信小程序,打开地图,跳转第三方

    一 需求 微信小程序 需要点击并跳转第三方地图软件导航 并计算到目标位置距离 二 思路 思路 1 接口返回需要有位置的经纬度 这个自行在后台编辑获取 2 需要获取用户的位置权限 我这边使用的是uniapp 需要使用官方封装两个接口 主要是用
  • 华为OD机试2023 最新最全备考攻略助你轻松上岸

    华为OD机试真题 2022 2023 真题目录 点这里 华为OD机试真题 信号发射和接收 试读 点这里 华为OD机试真题 租车骑绿道 试读 点这里 什么是华为OD 华为OD是Outsourcing Dispacth模式 是华为和外企德科联合
  • ubuntu系统火狐浏览器上网解决方法

    打开终端 sudo apt get update sudo apt get install firefox
  • VSCode本地代码同步服务器教程(已解决本地同步删除服务器端)

    1 安装插件 SFTP 2 1 在本地新建一个文件夹用来放项目 并且用vscode打开这个文件夹然后进行后续操作 2 2 在VSCode中打开命令栏 快捷键Shift Ctrl P 搜索SFTP 然后选择自己刚才创建的文件夹 3 选择SFT
  • 虚拟机和主机文件共享的四种方法

    第一种方法 使用虚拟机自带的共享功能 1 在vmware里VM gt 设置 gt options选项卡 gt shared folder 添加共享文件 具体如下图所示 2 然后到 mnt hgfs下可以找到共享的文件了 cd mnt hgf
  • 一些计算机词汇的简单解说

    fork zombie unix 中有个系统调用 叫做 fork 这个名字起得很有意思 两个fork 叉子 本来放在一起 跟着左右手各拿起一只 含着一分为二的意思 unix 中 fork 的作用就是创建了一个新的进程 和原来的进程是一模一样
  • java的基础知识-第四十篇-java中 =与==、&与&&、

    与 属于赋值运算符 将右侧的值赋给左侧的变量名称 属于关系运算符 判断左右两边的值是否相等 结果为boolear类型 与 是逻辑与 是短路与 都属于逻辑运算符 都表示并且执行结果都相同 当使用短路与 并且第一个条件为false时 则结果直接
  • linux系统时钟使用utc,linux时钟概念CST与UTC、以及NTP简单设置

    1 世界协调时间 Universal Time Coordinated UTC GPS 系统中有两种时间区分 一为UTC 另一为LT 地方时 两者的区别为时区不同 UTC就是0时区的时间 地方时为本地时间 如北京为早上八点 东八区 UTC时
  • 【PostgreSQL】行变列、非空(CASE WHEN、COALESCE)语句总结

    1 源表结构 order id class count 111101100002 3 0 111101100012 1 3 11110112002 1 2 111101100202 2 0 2 目标表结构 根据order id分组 根据不同
  • ubuntu执行编译命令提示"No such file or directory"

    uname a 查看系统是32位或64位 若是64位可能没有安装32位库 安装32位lib库 sudo apt get install nautilus open terminal bison zlib1g dev doxygen libx
  • 找不到vcruntime140.dll,无法继续执行代码?多种解决方法解析

    找不到vcruntime140 dll 无法继续执行代码 当你在尝试运行某个程序时 突然弹出一条错误提示框 告诉你无法继续执行代码 因为找不到vcruntime140 dll 这个问题很常见 但是它可能会让你感到困惑和疑惑 这篇文章将详细介
  • C# 定时器轮询 设计思路

    C 定时器设计过程的记录 在Windows 系统上 C 常用定时器有三种 而最高进度的定时器误差 58ms 则个误差数字无法应用 16ms 级别的定时轮询 但还有另外的高精度定时器 这不是还有其他方法吗 对有的 空转也指的是直接让线程一只空