打点计时器实验:实验分析C#中三种计时器使用异同点来源: 发布时间:星期四, 2009年2月12日 浏览:83次 评论:0
中提供了 3种类型计时器: 1、基于 标准计时器(..Forms.Timer) 2、基于计时器(.Timers.Timer) 3、线程计时器(.Threading.Timer) 下面我就通过些小实验来具体分析 3种计时器使用上面异同点特别是和线程有关部分 实验例子截图: 、基于 Windows 标准计时器(.Windows.Forms.Timer) 首先注意点就是:Windows 计时器是为单线程环境设计 此计时器从Visual Basic 1.0 版起就存在于该产品中并且基本上未做改动 这个计时器是使用最简单种只要把工具箱中TimerControl控件拖到窗体上然后设置下事件和间隔时间等属性就可以了 实验出来结果也完全符合单线程特点: 1、当启动此计时器后会在下方子线程ID列表中显示子线程ID并且和主线程ID相同 private void formsTimer_Tick(object sender EventArgs e) { i; lblSubThread.Text "子线程执行线程ID:" + .Threading.Thread.CurrentThread.ManagedThreadId.() + "\r\n"; } 2、当单击主线程暂停5秒后子线程会暂停执行并且当5秒的后不会执行的前被暂停子线程而是直接执行后面子线程(也就是会少输出几行值) .Threading.Thread.Sleep(5000); 3、在子进程事件中暂停5秒会导致主窗口相应无响应5秒 4、定义个线程静态变量: [ThreadStatic] private i = 0; 在子线程事件中每次加再点击线程静态变量值会得到增加后i值 2、基于计时器(.Timers.Timer) .Timers.Timer不依赖窗体是从线程池唤醒线程是传统计时器为了在服务器环境上运行而优化后更新版本 在VS2005工具箱中没有提供现成Control控件需要手工编码使用此计时器 使用方式有两种 1、通过SynchronizingObject属性依附于窗体 .Timers.Timer timersTimer = .Timers.Timer(); timersTimer.Enabled = false; timersTimer.Interval = 100; timersTimer.Elapsed .Timers.ElapsedEventHandler(timersTimer_Elapsed); timersTimer.SynchronizingObject = this; 通过这种方式来使用实验效果几乎和基于 Windows 标准计时器样只是在上面第 2条实验中虽然也会暂停子线程执行不过在5秒的后把的前排队任务都执行掉(也就是不会少输出几行值) 2、不使用SynchronizingObject属性 这种方式就是多线程方式了即启动子线程和主窗体不在个线程不过这样也存在个问题:由于子线程是单独个线程那么就不能访问住窗体中Control控件了只能通过代理方式来访问: delegate void SetTextCallback( text); void timersTimer_Elapsed(object sender .Timers.ElapsedEventArgs e) { //使用代理 text = "子线程执行线程ID:" + .Threading.Thread.CurrentThread.ManagedThreadId.() + "\r\n"; SetTextCallback d = SetTextCallback(SetText); this.Invoke(d object { text }); i; } private void SetText( text) { lblSubThread.Text text; } 这样我们再次实验就会得到如下结果: 1、当启动此计时器后会在下方子线程ID列表中显示子线程ID并且和主线程ID不相同 2、当单击主线程暂停5秒后子线程会直往下执行(界面上可能看不出来不过通过在子线程输出文件方式可以很方便看出来) 3、在子进程事件中暂停5秒不会导致主窗口无响应 4、在子线程事件中每次给线程静态变量加再点击线程静态变量值得到值还是0(不会改变主窗口中线程静态变量) 3、线程计时器(.Threading.Timer) 线程计时器也不依赖窗体是种简单、轻量级计时器它使用回调思路方法而不是使用事件并由线程池线程提供支持 对消息不在线程上发送方案中线程计时器是非常有用 使用思路方法如下: .Threading.Timer threadTimer; public void ThreadMethod(Object state) { //使用代理 text = "子线程执行线程ID:" + .Threading.Thread.CurrentThread.ManagedThreadId.() + "\r\n"; SetTextCallback d = SetTextCallback(SetText); this.Invoke(d object { text }); i; } private void Form1_Load(object sender EventArgs e) { threadTimer = .Threading.Timer( .Threading.TimerCallback(ThreadMethod) null -1 -1); } 暂停代码: threadTimer.Change(-1 -1); 实验效果和基于服务器计时器(.Timers.Timer)第 2种方式是样 当然具体使用思路方法和原理是不样最主要就是这种方式使用是代理方式而不是事件方式并且可以不依赖于窗体和组件而单独执行 下面列出老外整理总结张表( 3种方式区别): Feature description .Timers.Timer .Threading.Timer .Windows.Forms.Timer Support for adding and removing listeners after the timer is instantiated. Yes No Yes Supports call backs on the user-erface thread Yes No Yes Calls back from threads obtained from the thread pool Yes Yes No Supports drag-and-drop in the Windows Forms Designer Yes No Yes Suitable for running in a server multi-threaded environment Yes Yes No Includes support for passing arbitrary state from the timer initialization to the callback. No Yes No Implements IDisposable Yes Yes Yes Supports one-off callbacks as well as periodic repeating callbacks Yes Yes Yes Accessible across application do boundaries Yes Yes Yes Supports IComponent – hostable in an IContainer Yes No Yes 0
相关文章读者评论发表评论 |
|