没有合适的资源?快使用搜索试试~ 我知道了~
C#中自定义高精度Timer定时器的实例教程
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
5星 · 超过95%的资源 11 下载量 17 浏览量
2020-12-31
15:56:06
上传
评论
收藏 106KB PDF 举报
温馨提示
1、背景 在C#里关于定时器的类就有3个: (1)定义在System.Windows.Forms里 (2)定义在System.Threading.Timer类里 (3)定义在System.Timers.Timer类里 Timer 用于以用户定义的事件间隔触发事件。Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理。它要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。 使用此计时器时,请使用控件的Tick事件执行轮询操作,或在指定的时间内显示启动画面。每当 Enabled 属性设置为true且Interval属性大
资源详情
资源评论
资源推荐
C#中自定义高精度中自定义高精度Timer定时器的实例教程定时器的实例教程
1、背景、背景
在C#里关于定时器的类就有3个:
(1)定义在System.Windows.Forms里
(2)定义在System.Threading.Timer类里
(3)定义在System.Timers.Timer类里
Timer 用于以用户定义的事件间隔触发事件。Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理。它要求
用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。
使用此计时器时,请使用控件的Tick事件执行轮询操作,或在指定的时间内显示启动画面。每当 Enabled 属性设置为true且
Interval属性大于0时,将引发Tick事件,引发的时间间隔基于Interval属性设置。
System.Windows.Forms.Timer是应用于WinForm中的,他是通过Windows消息机制实现的,类似于VB或Delphi中的Timer控
件,内部使用API SetTimer实现的。他的主要缺点是计时不精确,而且必须有消息循环,Console Application(控制台应用程
式)无法使用。
System.Timers.Timer和System.Threading.Timer很类似,他们是通过.NET Thread Pool实现的,轻量,对应用程式、消息没
有特别的需要。System.Timers.Timer还能够应用于WinForm,完全取代上面的Timer控件。
然而其精度都不高(一般情况下 15ms 左右),难以满足一些场景下的需求。
在进行媒体播放、绘制动画、性能分析以及和硬件交互时,可能需要 10ms 以下精度的定时器。这里不讨论这种需求是否合
理,它是确实存在的问题,也有相当多的地方在讨论,说明这是一个切实的需求。然而,实现它并不是一件轻松的事情。
这里并不涉及内核驱动层面的定时器,只分析在 .NET 托管环境下应用层面的高精度定时器实现。
Windows 不是实时操作系统,所以任何方案都无法绝对保证定时器的精度,只是能尽量减少误差。所以,系统的稳定性不能
完全依赖于定时器,必须考虑失去同步时的处理。
2、等待策略、等待策略
想要实现高精度定时器,必然需要等待和计时两种基础功能。等待用来跳过一定时间间隔,计时可以进行时间检查,用以调整
等待时间。
等待策略实际就是两种:
自旋等待:让 CPU 空转消耗时间,占用大量 CPU 时间,但是时间高度可控。
阻塞等待:线程进入阻塞状态,出让 CPU 时间片,在等待一定时间后再由操作系统调度回到运行状态。阻塞时不占用 CPU,
然而需要操作系统调度,时间难以控制。
可以看到二者各有优劣,应该按照不同需求进行不同的实现。
而计时机制可以说能用的只有一种,就是Stopwatch类。它内部使用了系统 API QueryPerformanceCounter/
QueryPerformanceFrequency来进行高精度计时,依赖于硬件,它的精度可以高达几十纳秒,非常适合用来实现高精度定时
器。
所以难点在于等待策略,下面先分析简单的自旋等待。
2.1自旋等待自旋等待
可以使用Thread.SpinWait(int iteration)来进行自旋,也就是让 CPU 在一个循环里空转,iteration参数是迭代次数。.NET
Framework 中不少同步构造都用到了它,用来等待一小段时间,减少上下文切换的开销。
这里很难根据iteration来计算消耗的时间,因为 CPU 速度可能是动态的。所以需要结合使用Stopwatch。伪代码如下:
var 等待开始时间 = 当前计时;
while ((当前计时 - 等待开始时间) < 需要等待的时间)
{
自旋;
}
写成实际代码:
void Spin(Stopwatch w, int duration)
{
var current = w.ElapsedMilliseconds;
while ((w.ElapsedMilliseconds - current) < duration)
Thread.SpinWait(10);
}
这里的w是一个已经启动的Stopwatch,为了演示简单使用了ElapsedMilliseconds属性,精度是毫秒级的,使用ElapsedTicks
weixin_38739942
- 粉丝: 5
- 资源: 953
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论3