c#windows 多媒体定时器器精度高吗

c#计时器怎样精确到秒,写精确度太高了。下面是代码_百度知道
c#计时器怎样精确到秒,写精确度太高了。下面是代码
private void button1_Click(object sender, EventArgs e)
startTime = DateTime.N
MessageBox.Show(&计时开始!&);
private void button2_Click(object sender, EventArgs e)
我有更好的答案
用TimeSpan
为您推荐:
其他类似问题
您可能关注的内容
计时器的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。这两天正在准备做一个实时控制的东西,想用C#。可是昨天日本人展示了一个在LINUX平台下使用C语言控制的单自由度机械臂,我问他们为什么不用WINDOWS,他们说用WINDOWS编程实时性很差,定时很不准,所以用了LINUX,为了兼容性好,服务器也用的是LINUX平台,用于网络控制。可是如果网络也用C或C++的话编程肯定比较慢,还是想用C#编程,于是今天就研究了一下C#中定时器的问题。
在.Net Framework中在三个地方有定时器类分别是System.Timers.Timer, System.Threading.Timer和System.Windows.Form.Timer。与了个程序分别对这三个类进行了测试,精度的确差得不能用,三个定时精度都差不多,最好可以到15ms左右,但很不稳定,定时间隔误差比较大,五般在15个ms左右,甚至更多,经过MATLAB画出的曲线看,误差还是有规律的,下面是定时间隔为40ms时,定时器中断服务函数相临两次响应之间的时间间隔采样数据连线图。
由图中可以看出,在很多时候实际响应时间要比设定时间晚10毫秒左右,但采样时间都已经40ms了,如果把采样时间再调小一些误差会更大,而且经过测试,最小间隔只能到15ms,即使把间隔调成1ms,实际响应时间都在15ms以上,这种精度在实时控制中几乎不能接受,故而需要使用其它方法提高定时器的精度。
因为WINDOWS是多任务的操作系统,定时器的延时可能是由于其它任务占用CPU资源,没能及时响应定时器事件,如果能够改变定时器线程的优先级应该也可以改善定时器的精度,但查了一些资料也没有看到能够控制那些定时器类封装的纯种的优先级的资料,因为这些类都没有提供控制定时器所在线程的优先级的接口。故而想自己构造一个高精度的定时器,使得精度尽量能达到1ms。
在查阅资料中发现两篇文章很有用,一个是介绍VC使用WIN32API函数
/// Pointer to a variable that receives the current performance-counter value, in counts.
/// If the function succeeds, the return value is nonzero.
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpPerformanceCount);
/// Pointer to a variable that receives the current performance-counter frequency,
/// in counts per second.
/// If the installed hardware does not support a high-resolution performance counter,
/// this parameter can be zero.
/// If the installed hardware supports a high-resolution performance counter,
/// the return value is nonzero.
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);
另一篇就是介绍在C#中使用这两个函数的方法了,也就是上面的代码。QueryPerformanceFrequency 函数是读取系统所支持的硬件定时器计数频率,也就是每秒的计数值,QueryPerformanceFrequency 应该是从开机时的计数值。这样通过读取两次计数值之差,再除以计数频率也就是两次读取时钟间隔的秒数。然后通过查询两次的间隔来确定是否响应服务函数,封装了如下类:
/// ManualTimer
/// A simulated timer by loop
/// It creates a new thread in Thread Pool using ThreadPool class
/// Nocky Tian @
/// The timer starts a new thread using
/// and the value of the property Priority is set to
/// so that the accuray could be kept 1ms around.
public class UltraHighAccurateTimer
public event ManualTimerEventH
private object threadLock = new object();
// for thread safe
private long clockF
// result of QueryPerformanceFrequency()
bool running =
private int intervalMs;
/// Timer inteval in milisecond
public int Interval
get { return intervalMs; }
intervalMs =
intevalTicks = (long)((double)value * (double)clockFrequency / (double)1000);
private long intevalT
private long nextTriggerT
// the time when next task will be executed
/// Pointer to a variable that receives the current performance-counter value, in counts.
/// If the function succeeds, the return value is nonzero.
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
/// Pointer to a variable that receives the current performance-counter frequency,
/// in counts per second.
/// If the installed hardware does not support a high-resolution performance counter,
/// this parameter can be zero.
/// If the installed hardware supports a high-resolution performance counter,
/// the return value is nonzero.
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out
long lpFrequency);
protected void OnTick()
if (tick != null) {
public UltraHighAccurateTimer()
if (QueryPerformanceFrequency(out clockFrequency) == false) {
// Frequency not supported
throw new Win32Exception("QueryPerformanceFrequency() function is not supported");
thread = new Thread(new ThreadStart(ThreadProc));
thread.Name = "HighAccuracyTimer";
thread.Priority = ThreadPriority.H
/// 进程主程序
private void ThreadProc()
long currT
GetTick(out currTime);
nextTriggerTime = currTime + intevalT
while (running) {
while (currTime & nextTriggerTime) {
GetTick(out currTime);
// wailt an interval
nextTriggerTime = currTime + intevalT
//Console.WriteLine(DateTime.Now.ToString("ss.ffff"));
if (tick != null) {
public bool GetTick(out long currentTickCount)
if (QueryPerformanceCounter(out currentTickCount) == false)
throw new Win32Exception("QueryPerformanceCounter() failed!");
public void Start()
thread.Start();
public void Stop()
~UltraHighAccurateTimer()
thread.Abort();
本来上面的类是用线程池创建的定时器线程,使用的ThreadPool类,但是精度不高,只能到5ms,或4ms,不是很满意,改用Thread类,将其优秀级提到最高,精度可以达到1ms. 可能是操作系统调整优先级顺序问题,采样200次,发现到四十几次以后精度才能到1ms,一开始采样间隔有2~3ms,尝试一开始先运行一段空程序,使线程进入正常以后才开始定时器的工作,可基本没有什么改善,也有可能等待的时间不够。
上面的程序在VISTA上测试过,可以达到1ms的精度,但需要一个过渡期。可能是由于任务太多造成的,因为在测试程序中把时间显示到终端屏幕了,而且里面有一些字符串格式化操作,会比较占用资源,而且使用了delegate作为事件代理,可能性能有所损失,以后再研究一下delegate对性能损失的程度。
如果系统对实时性要求比较高,可以不对定时器进行封装,将定时器的主进程当作控制器采样的主进程,减少函数调用造成的CPU资源浪费,精度会更高。
yidongkaifa
浏览: 1941389 次
废话啊啊啊
iOS: 当发生signal 9为 kill的时候,程序直接被 ...
给的地址,没豆子呢,能单独发一份给我吗,andsy2008@1 ...
[b][i][u]引用[list]
[*][flash=200 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'C# 各种定时器比较_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
C# 各种定时器比较
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢C#定时器里面调试代码,注意在调试的时候_百度知道
C#定时器里面调试代码,注意在调试的时候
设置定时器interval为10S,你在按F11的时候10S后又会调到调试点,如果设置interval为1S的话,就会不停地返回调试点,感觉在时间到了之后就自动创建线程。。
我这样的理解对吗
我有更好的答案
定时器利用的是消息机制,是在后台运行的,你设断点的时候,时间还在计算,到时间还会继续走定时器的。通常定时器使用是 进入定时器 先将定时器停止,然后直行所有代码完毕后 再将定时器开启
恩,调试的时候如何将定时器先停止啊,那我自己写的Timers.timer定时器属于后台线程吗?
我看到有人这样说“手动新开一个线程会增大程序开启线程的数量,默认是前台线程”,这个对吗?
t.isbackground是可以设置的吧。
isbackground设置为true 就是后台线程了,调试的时候 你就timer的tick事件
先写上 timer.stop()然后 等执行完了 在start()就行了啊
好的,定时器应该是后台线程。手动新开一个线程如果不设置,默认是前台线程,是吗?
是的 默认是前台线程
那么就会开启下一个Tick事件。举个例子,你的定时器interval设定为1S,实际后台运行的线程还没关闭是的如果你没有停止定时器。但是这样是不好的,一般会造成竞争和程序堵塞,当你关闭程序窗口后:一是在程序里加入明确的线程停止的标记,一旦达到这个条件就开始关闭该线程,那么问题就来了,一般就两种,而还未完成的Tick事件则会继续执行,这样就会有两个线程在执行,那么你可以考虑将interval设定的更大一些以是程序有足够时间等待该线程结束。代码还没执行完毕,1S就已经过去了,但是在你的Tick事件里需要执行的代码至少需要1.5S才能执行完毕。二是如果你确认线程达到某个时候就一定会关闭的话。处理这种情况,根据我的一些做法,那么它就会按照你设定的时间按时开启Tick事件
恩,调试的时候如何将定时器先停止啊,那我自己写的Timers.timer定时器属于后台线程吗?
我看到有人这样说“手动新开一个线程会增大程序开启线程的数量,默认是前台线程”,这个对吗?
t.isbackground是可以设置的吧。
为您推荐:
其他类似问题
定时器的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。本帖子已过去太久远了,不再提供回复功能。

我要回帖

更多关于 多媒体定时器 线程 的文章

 

随机推荐