三分钟解决VB.NET定时器事件重入

开发 后端
这里介绍了VB.NET定时器事件处理重入,假设你的定时器间隔属性设置为1000毫秒,你也许会奇怪当第一个信息框弹出时显示的值是5。

喜欢VB.NET朋友一定会很喜欢研究定时器方面的问题吧。本人就很喜欢,在网上我收集了很多东西,在这个就VB.NET定时器事件重入的问题来和大家一起探讨一下。不论在客户端应用程序还是服务器组件(包括窗口服务)定时器通常扮演一个重要的角色。写一个高效的定时器驱动型可管理代码要求对程序流程有一个清晰的理解及掌握.NET线程模型的精妙之处。.NET框架类库提供了三种不同的定时器类:System.Windows.Forms.Timer, System.Timers.Timer, 和System.Threading.Timer。每个类为不同的场合进行设计和优化。本文章将研究这三个类并让你理解如何及何时应该使用哪一个类。

VB.NET定时器事件处理重入

当和异步定时器事件打交道时,如由System.Timers.Timer和System.Threading.Timer产生的定时器事件,有另外一个细微之处你需要考虑。问题就是必须处理代码重入。如果你的定时器事件处理函数代码执行时间比你的定时器引发定时器事件的时间间隔要长,你预先又没有采取必要的措施保护防止多线程访问你的对象和变量,你就会陷入调试的困境。看一下下面的代码片断:

  1. private int tickCounter = 0;  
  2. private void tmrTimersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgse)  
  3. {  
  4. System.Threading.Interlocked.Increment(ref tickCounter);   
  5. Thread.Sleep(5000);   
  6. MessageBox.Show(tickCounter.ToString());  

假设你的定时器间隔属性设置为1000毫秒,你也许会奇怪当***个信息框弹出时显示的值是5。这是因为在这5秒期间***个定时器事件正在睡眠,而定时器却在不同的工作者线程上继续产生时间消失事件。因此,在***个VB.NET定时器事件处理完成之前tickCounter变量被增加了5次。注意我使用了Interlocked.Increment方法以线程安全的方式增加tickCounter变量的值。也有其它方法可以这样做,但是Interlock.Increment是为这种操作而特别设计的。

解决这种问题的简单方法就是在你的事件处理函数代码块中暂时禁止定时器,接着再允许定时器,就像下面的代码:

  1. private void tmrTimersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgse)  
  2. {  
  3. tmrTimers.Enabled = false;   
  4. System.Threading.Interlocked.Increment(ref tickCounter);   
  5. Thread.Sleep(5000);   
  6. MessageBox.Show(tickCounter.ToString());  
  7. tmrTimersTimer.Enabled = true;  

有了这段代码,消息框就会每5秒钟显示一次,就像你所期望的那样,tickCounter的值每次只增加1。另外一些可选的原始同步对象就是Monitor或mutex去确保所有将来的事件被排队直到当前的事件处理函数执行完成。

结论
当使用定时器类时有一点你要考虑的就是是否可以使用Windows调度器去定期的运行标准的可执行程序来更简单的解决问题。

【编辑推荐】

  1. 剖析VB.NET平台调用是如何执行操作
  2. 分享个人总结VB.NET多线程
  3. VB.NET初步知识,初学者必看
  4. VB.NET函数宝典手把手教会你
  5. VB.NET动态控件数组三部曲
责任编辑:田树 来源: 赛迪网
相关推荐

2009-11-10 16:05:21

VB.NET格式化

2009-10-26 19:09:50

VB.NET转换形态

2009-10-29 16:22:10

VB.NET操作MyS

2009-11-03 17:15:07

VB.NET开发Exc

2024-01-16 07:46:14

FutureTask接口用法

2021-04-20 13:59:37

云计算

2022-02-17 09:24:11

TypeScript编程语言javaScrip

2023-12-27 08:15:47

Java虚拟线程

2009-11-03 11:01:45

VB.NET远程事件

2021-12-17 07:47:37

IT风险框架

2009-11-05 16:04:19

Oracle用户表

2024-01-12 07:38:38

AQS原理JUC

2021-02-03 14:31:53

人工智能人脸识别

2023-12-04 18:13:03

GPU编程

2020-06-29 07:42:20

边缘计算云计算技术

2009-10-26 15:45:43

VB.NET类构造

2009-10-21 18:19:36

VB.NET实现拖放

2009-11-09 12:55:43

WCF事务

2023-12-22 09:37:13

二分查找数组数据库

2009-10-30 13:12:40

VB.NET创建类
点赞
收藏

51CTO技术栈公众号