winform里timer定时周期

p入门到崛起q 2017-01-09 10:42:20
问题提出:timer的Interval设置为1(理论上即1ms触发一次Tick事件),timer_Tick函数里代码如图一所示,但是通过手机计时器 计时30s,观察timer_Tick里更新的textbox的值,如图二所示。手机计时的30s对应只触发了3533次(即3.5s),与实际很不符合。


求助:各位前辈,有没有定时精准的方法可以提供点线索?
...全文
468 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
佳佳顿 2017-01-11
  • 打赏
  • 举报
回复
这么精确的计时实现不了。。
john_QQ:2335298917 2017-01-09
  • 打赏
  • 举报
回复
http://blog.csdn.net/chenlycly/article/details/16479519
Forty2 2017-01-09
  • 打赏
  • 举报
回复
引用 楼主 sinat_19596835 的回复:
...有没有定时精准的方法可以提供点线索?
如果你的需求是1ms的‘实时’准确控制(比如火箭姿势调整),其实Windows操作系统并不适合。 因为它是‘抢占式’多任务操作系统。操作系统可以随时进行干预(抢占式)调度,让哪个线程运行,以及运行多久。 开定时器也好,Thread.Sleep也好,一旦你让出了CPU,你被重新唤醒的时间并没有保证。 即使你不让出CPU,开一个线程不停spin wait,你的线程也可能被操作系统抢占。
john_QQ:2335298917 2017-01-09
  • 打赏
  • 举报
回复
的确,windows的定时器机制比较粗糙,有一个高精度的定时器用于媒体播放,你可以搜一下相关的资料,不过也达不到1ms
闭包客 2017-01-09
  • 打赏
  • 举报
回复
我试过了,的确如楼上所说,达不到 1ms
Forty2 2017-01-09
  • 打赏
  • 举报
回复
你不能依赖于timer1_Tick的执行来累计计时。两个原因, 一是出于操作系统机制,Widnows Timer的颗粒比较粗,没有精确到1ms级别(可能约15ms)。 二是System.Windows.Forms 命名空间的Timer事件是低优先级消息,可以被跳过。 因此,你应该用DateTime.Now来计时。
闭包客 2017-01-09
  • 打赏
  • 举报
回复
引用 3 楼 sinat_19596835 的回复:
[quote=引用 1 楼 closurer 的回复:] 使用 timer 是没有问题的。 问题是没有线程同步。
前辈能不能再深入一点?这里的timer不是在UI线程里么?是需要给timer重建个线程么?[/quote] 晕,我搞错了。System.Windows.Forms 命名空间的 Timer 是不需要同步的。
闭包客 2017-01-09
  • 打赏
  • 举报
回复
引用 3 楼 sinat_19596835 的回复:
[quote=引用 1 楼 closurer 的回复:] 使用 timer 是没有问题的。 问题是没有线程同步。
前辈能不能再深入一点?这里的timer不是在UI线程里么?是需要给timer重建个线程么?[/quote] 不需要,timer 只是看上去在 UI 线程,实际上并不是。 你要这样去同步线程:

lock(Data)
{
    Data++;
    textBox1.Text = Data.ToString();
}
p入门到崛起q 2017-01-09
  • 打赏
  • 举报
回复
引用 1 楼 closurer 的回复:
使用 timer 是没有问题的。 问题是没有线程同步。
前辈能不能再深入一点?这里的timer不是在UI线程里么?是需要给timer重建个线程么?
p入门到崛起q 2017-01-09
  • 打赏
  • 举报
回复
前辈能不能再深入一点?这里的timer不是在UI线程里么?是需要给timer重建个线程么?
闭包客 2017-01-09
  • 打赏
  • 举报
回复
使用 timer 是没有问题的。 问题是没有线程同步。
p入门到崛起q 2017-01-09
  • 打赏
  • 举报
回复
引用 13 楼 closurer 的回复:
[quote=引用 12 楼 sinat_19596835 的回复:] [quote=引用 4 楼 closurer 的回复:] [quote=引用 3 楼 sinat_19596835 的回复:] [quote=引用 1 楼 closurer 的回复:] 使用 timer 是没有问题的。 问题是没有线程同步。
前辈能不能再深入一点?这里的timer不是在UI线程里么?是需要给timer重建个线程么?[/quote] 不需要,timer 只是看上去在 UI 线程,实际上并不是。 你要这样去同步线程:

lock(Data)
{
    Data++;
    textBox1.Text = Data.ToString();
}
[/quote] 这里的lock好像不能对值类型进行lock[/quote] 嗯,这个方法行不通,抱歉![/quote] 还是谢谢你!
闭包客 2017-01-09
  • 打赏
  • 举报
回复
引用 12 楼 sinat_19596835 的回复:
[quote=引用 4 楼 closurer 的回复:] [quote=引用 3 楼 sinat_19596835 的回复:] [quote=引用 1 楼 closurer 的回复:] 使用 timer 是没有问题的。 问题是没有线程同步。
前辈能不能再深入一点?这里的timer不是在UI线程里么?是需要给timer重建个线程么?[/quote] 不需要,timer 只是看上去在 UI 线程,实际上并不是。 你要这样去同步线程:

lock(Data)
{
    Data++;
    textBox1.Text = Data.ToString();
}
[/quote] 这里的lock好像不能对值类型进行lock[/quote] 嗯,这个方法行不通,抱歉!
p入门到崛起q 2017-01-09
  • 打赏
  • 举报
回复
引用 4 楼 closurer 的回复:
[quote=引用 3 楼 sinat_19596835 的回复:] [quote=引用 1 楼 closurer 的回复:] 使用 timer 是没有问题的。 问题是没有线程同步。
前辈能不能再深入一点?这里的timer不是在UI线程里么?是需要给timer重建个线程么?[/quote] 不需要,timer 只是看上去在 UI 线程,实际上并不是。 你要这样去同步线程:

lock(Data)
{
    Data++;
    textBox1.Text = Data.ToString();
}
[/quote] 这里的lock好像不能对值类型进行lock
p入门到崛起q 2017-01-09
  • 打赏
  • 举报
回复
引用 9 楼 Forty2 的回复:
[quote=引用 楼主 sinat_19596835 的回复:] ...有没有定时精准的方法可以提供点线索?
如果你的需求是1ms的‘实时’准确控制(比如火箭姿势调整),其实Windows操作系统并不适合。 因为它是‘抢占式’多任务操作系统。操作系统可以随时进行干预(抢占式)调度,让哪个线程运行,以及运行多久。 开定时器也好,Thread.Sleep也好,一旦你让出了CPU,你被重新唤醒的时间并没有保证。 即使你不让出CPU,开一个线程不停spin wait,你的线程也可能被操作系统抢占。 [/quote] 也对,windows本身就不是硬实时系统,可能是我设计思路出问题了; 我是在chart控件里用1ms来添加数据点,来跟上串口9600的波特率,不然会有很大的延迟(即串口传输线拔了,上位机还在显示数据)......不知道前辈有没有经验?

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧