我有一个类,创build一个新的计时器,并轮询每个滴答远程队列(通过http)。
public voID Start() { _timer = new Timer((x) => { Console.Writeline(DateTime.Now.ToString("hh:MM:ss.fff") + " " + typeof(T).name); var message = (Message)null; var messageBody = (T)null; try { if (!_queue.TryGet(out message)) return; messageBody = (T)JsonConvert.DeserializeObject(message.Body,typeof(T)); _messagedispatcher.dispatch<T>(messageBody); _queue.Delete(message.ID); } catch (Exception ex) { _errorHandler.Handle(ex,message); } },null,_queueConsumerConfiguration.PollingInterval); } }
如果我创build了这个类的八个新实例,将轮询间隔设置为250ms,并调用它们,我假devise时器将非常准确地打勾。 定时器callback内部执行什么都不重要。 然而,这种情况并非如此。
01:03:23.305 MessageSleepForOnesecond 01:03:23.301 MessageSleepForOnesecond 01:03:23.297 MessageSleepForOnesecond 01:03:23.316 MessageSleepForOnesecond 01:03:24.321 MessageSleepForOnesecond 01:03:24.562 MessageSleepForOnesecond 01:03:24.701 MessageSleepForOnesecond 01:03:24.707 MessageSleepForOnesecond 01:03:24.716 MessageSleepForOnesecond 01:03:25.321 MessageSleepForOnesecond 01:03:25.518 MessageSleepForOnesecond 01:03:25.764 MessageSleepForOnesecond 01:03:25.912 MessageSleepForOnesecond 01:03:25.920 MessageSleepForOnesecond 01:03:25.924 MessageSleepForOnesecond 01:03:26.521 MessageSleepForOnesecond 01:03:26.710 MessageSleepForOnesecond 01:03:26.957 MessageSleepForOnesecond 01:03:27.107 MessageSleepForOnesecond 01:03:27.120 MessageSleepForOnesecond 01:03:27.126 MessageSleepForOnesecond 01:03:27.716 MessageSleepForOnesecond 01:03:27.906 MessageSleepForOnesecond 01:03:28.151 MessageSleepForOnesecond 01:03:28.305 MessageSleepForOnesecond 01:03:28.316 MessageSleepForOnesecond 01:03:28.322 MessageSleepForOnesecond 01:03:28.913 MessageSleepForOnesecond 01:03:29.100 MessageSleepForOnesecond 01:03:29.349 MessageSleepForOnesecond 01:03:29.502 MessageSleepForOnesecond 01:03:29.513 MessageSleepForOnesecond 01:03:29.538 MessageSleepForOnesecond 01:03:30.107 MessageSleepForOnesecond 01:03:30.297 MessageSleepForOnesecond 01:03:30.545 MessageSleepForOnesecond 01:03:30.705 MessageSleepForOnesecond 01:03:30.712 MessageSleepForOnesecond 01:03:30.733 MessageSleepForOnesecond 01:03:31.307 MessageSleepForOnesecond 01:03:31.310 MessageSleepForOnesecond ...
这是怎么回事? 什么原因导致不准确? ThreadPool,windows的pipe理…?
在两个窗体之间传递值
窗口,设置电脑(浏览器)的默认网页代理
可以通过使用System.IO库来读取文件来执行病毒吗?
制作autorun应用程序的最佳解决scheme?
从windows服务启动一个windows应用程序
如何编译执行时不显示“未知发布者”的C#程序
使用P /调用的GlobalSize时堆损坏
如何从exe文件中提取与用于创build此exe文件相同的.ico文件?
Microsoft.SharePoint.PowerShellpipe理单元:不正确的windows PowerShell版本3.0。 当前控制台支持Window PowerShell 2.0版
是否可以使用extern和overrIDe修饰符指定一个函数?
定时器不是无限准确的,线程调度并不是无限准确的。 在当前版本的windows(15岁以上的windows大约50ms)内,其中任何一个都可以在timeBeginPeriod 1ms(通过timeBeginPeriod配置)和默认16.7ms的任何位置进行精度测量。
一个计时器本身并不是无限精确的,它会产生一个事件,使线程池中的线程就绪,这个线程将在后面的任何时间被调度,而不是准确的,没有任何硬性的保证。 如果其他线程正在运行,那么随后的“随时”可能会根据处理器的负载和线程的优先级,在以后的任何时候 (甚至从不)。
单靠这一点已经足够了,为什么通常没有你选择的间隔是准确的(除非是巧合),但是特别是250ms的间隔不会是(因为249ms是调度程序默认粒度的最接近的倍数,所以一个新的线程可以在最好在265.6ms之后安排 – 而且这个假设是在一个确切的时间有一个核心,这是不能保证的)。
另外,处理http请求可能花费相当不重要的时间,所以即使没有其他线程,也可能创建比核心更多的工作者。 这必然意味着 *** 作系统必须决定在特定时间安排哪一个。 无论调度员做什么,最终总会对一个或几个线程产生“不公平”的情况,导致他们“不准确”。
写入控制台也是如此。 写入控制台是同步的(即,当你的两个线程写入控制台时,单个写入可能以任意顺序出现,但它们不是乱码)。 这意味着有一个锁。 谁先得到锁,继续。 谁试图获得锁定纳秒后将被阻止。 其他一些线程占用了时间片。 最后,被阻塞的线程将被重新设置为“准备就绪”,但是没有严格保证该线程将立即运行。
准备好跑步和跑步是两件非常不同的事情。
总结以上是内存溢出为你收集整理的是什么让我的计时器跑不准?全部内容,希望文章能够帮你解决是什么让我的计时器跑不准?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)