DotNet注意点:System.Timer和Thread.timer和Form.timer

来源于:http://topic.csdn.net/t/20060413/14/4684297.html

System.Timer,通常执行正常。 

但是在系统资源(CPU)占用比较厉害的时候,有可能System.Timer.Enabled=true后,并不产生作用。 
也有可以执行几次后,就不再执行了。 
出现在几率大概在0.5%左右 
我的程序中还有Form.Timer,现在用Form.Timer附带做了对此System.timer的监视,发现问题,则写日志,并执行:
System.Timer.Enabled=false 
System.Timer.Enabled=true; 
暂时避免了此BUG带来的不良影响,正在测试发生此种问题的根源,以找到更好的方式来避免。 
但是,还不知道form.timer是否也会存在这种BUG,目前我还没有遇到过。 
有没有遇到类式问题的朋友????   给点参考意见啊 

两天之内,无论如何,结贴,希望在结贴之前能有更好的处理方案

--

如果此问题无法避免,打算在程序中开三个专用timer:   来自System,Thread,Form 
3个timer互相监视,并统一触犯事件,检测系统中的所有timer的状态,发现问题,重启。 
虽然感觉这种方式有点弱智

--

为什么不用Thread来代替呢。 
Timer需要Message来响应,即是被动触发,当系统cpu资源紧张的时候,就会出现你上面的现象。 

--

回愚翁: 
用Timer,感觉写代码要方便一些。   当Timer的指针丢失的时候,Timer执行会自动被干掉,而Thread的运行,必须要想办法对它停止才行。 
当然,使用起来,关闭Thread也没有程序难度。 
用(Timer间隔调用),或是(用Thread,通过循环并且Sleep进行调用),当资源(比如CPU)占用高的时候,都会出现实际间隔比指定的间隔时间大很多的情况。这个我在很久以前就测试过了 
但是在实际使用中,这个影响不会很大。   比如,指定5秒的间隔,实际上由于资源方面的情况,间隔了50秒,也不会影响程序的正常运行,完全可以接受。 
但是,居然Timer会执行停,比如: 
1、timer在start之后,一次事件都不触发 
2、timer在start之后,触发几次之后,就不再触发事件了 
这就是我以前完全没有考虑到的问题。   现在的程序中有十多个System.Timer,全部用保护代码做重启动timer处理,代码量还是比较大的。 
打算先写的个循环测试System.timer开启的程序,看看有无办法在开timer时的代码方面做一些改动,杜绝这种情况的发生。 
现在手动一次一次开程序测试,面对差不多0.5%的出错记录,今天下午点鼠标都要点疯了:(

--

to   lw8122(随风) 

线程写多了,你会发现它的好处,其实处理并不复杂,而且控制权在你手中。

--

to:   愚翁 
线程,我已经用得非常多了,并且在手动制造的最恶劣的环境(不停止的疯狂连接,导致未执行完的线程不断堆积)中出现了BUG。 
于是做测试代码,测试结果:在一个程序中(也可能是一个主线程中,但我没试两个主线程中大量开线程),开启线程的最大数量为1800多个(注:这里我所说的线程,是指开启,并且未执行完毕的线程),然后再开就会失败。 
但把这个程序开N个,那么N个程序都会在1800多个子线程时出错。 
于是,做了容错代码,在线程达到500个的时候,不再允许连接。   直到线程低于500个时,再继续允许连接:)

--

基本有了结论。 
System.timer的确有可能在资源过大的情况下停掉,   Thread.timer和form.timer目前都没有停过。 
今天再继续测试,如果到下班form.timer都还无问题,以后就全部改用form.timer了 
以下是我花1小时写的测试timer开启情况的源代码,一台PC上开10个,然后监视三种timer的启动情况 
每一个timer,在执行3次后,将被重启。
tmTotal用于统计每个timer重新开启的次数,当一个timer不执行时,就说明出问题了 

代码基本无注释,大家有兴趣就研究一下吧。 

--

用程序做了测试,结论: 
System.timer是最不稳定的,在系统资源大的时候,有可能会在开启的时候失效,几率不大,几千分之一。 
而Form.timer和Thread.timer,则没有任何问题,开启一定成功。 
将把程序中的System.timer全部换为Form.timer,解决些问题。 
结贴 

----



system.timer没有 System.Threading.Timer 好用

来源于:http://blog.sina.com.cn/s/blog_62c501440100fog1.html


System.Threading.Timer 是一个非常常用的定时器类,关于这个类的使用,我们需要注意以下几点:
   1.System.Threading.Timer 的任何一个实例,实际上是通过使用win32底层(非.NET Thread Pool中的线程)来进行调度的。
   2.当到达调度时刻时,System.Threading.Timer 将异步调用由TimerCallback参数指定的回调方法。也就是说TimerCallback所指向的方法将在.NET Thread Pool中的工作者线程中执行。
   3.当.NET Thread Pool中没有空闲线程时,对TimerCallback所指向的方法的调用将被ThreadPool排队。而这并不会影响System.Threading.Timer的正常调度过程--当到达调度时间点,System.Threading.Timer仍然触发异步调用。
   顺便补充一下,经过我的测试发现,ThreadPool中默认的最大工作线程数是25/CPU,最大完成端口线程
数是1000。(双核最大工作线程就是25*2/CPU)
 

System.Threading.Timer 是一个使用回调方法的计时器,而且由线程池线程服务,简单且对资源要求不高。
只要在使用  Timer ,就必须保留对它的引用。对于任何托管对象,如果没有对  Timer  的引用,计时器会被垃圾回收。即使  Timer  仍处在活动状态,也会被回收。当不再需要计时器时,请使用  Dispose  方法释放计时器持有的资源。
 
使用  TimerCallback  委托指定希望  Timer  执行的方法。计时器委托在构造计时器时指定,并且不能更改。此方法不在创建计时器的线程中执行,而是在系统提供的线程池线程中执行。
 
创建计时器时,可以指定在第一次执行方法之前等待的时间量(截止时间)以及此后的执行期间等待的时间量(时间周期)。可以使用  Change  方法更改这些值或禁用计时器。

Demo application:
应用场景:在 windows form 程序自动执行某项工作后,希望其 windows form 能够自动关闭。
代码设计:( 1 )首先声明 Timer 变量:
private  System.Threading.Timer timerClose;
 
2 )在上述自动执行代码后面添加如下 Timer 实例化代码:
// Create a timer thread and start it
timerClose  new System.Threading.Timer(new TimerCallback(timerCall), this, 5000, 0);
 
Timer 构造函数参数说明:
Callback 一个  TimerCallback  委托,表示要执行的方法。
State 一个包含回调方法要使用的信息的对象,或者为空引用( Visual Basic  中为  Nothing
dueTime 调用  callback  之前延迟的时间量(以毫秒为单位)。 指定  Timeout.Infinite  以防止计时器开始计时。指定零  (0)  以立即启动计时器。
Period :调用  callback  的时间间隔(以毫秒为单位)。 指定  Timeout.Infinite  可以禁用定期终止。
 
3 )定义 TimerCallback 委托要执行的方法:
private  void timerCall(object obj)
{
      timerClose.Dispose();
      this.Close();
}
 
当然,除了使用上述 System.Threading.Timer 类的 TimerCallback  委托机制外,应该还有很多其他的办法。另外,这里只是 demo TimerCallback 委托的简单应用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值