二、基于服务器的计时器(System.Timers.Timer)
System.Timers.Timer不依赖窗体,是从线程池唤醒线程,是传统的计时器为了在服务器环境上运行而优化后的更新版本
在VS2005的工具箱中没有提供现成的控件,需要手工编码使用此计时器
使用方式有两种,
1、通过SynchronizingObject属性依附于窗体
通过这种方式来使用,实验效果几乎和基于 Windows 的标准计时器一样,只是在上面的第二条实验中,虽然也会暂停子线程的执行,不过在5秒之后把之前排队的任务都执行掉(也就是不会少输出几行值)System.Timers.Timer timersTimer = new System.Timers.Timer(); timersTimer.Enabled = false; timersTimer.Interval = 100; timersTimer.Elapsed += new System.Timers.ElapsedEventHandler(timersTimer_Elapsed); timersTimer.SynchronizingObject = this;
2、不使用SynchronizingObject属性
这种方式就是多线程的方式了,即启动的子线程和主窗体不在一个线程。不过这样也存在一个问题:由于子线程是单独的一个线程,那么就不能访问住窗体中的控件了,只能通过代理的方式来访问:
这样我们再次实验就会得到如下的结果:delegate void SetTextCallback(string text); . . void timersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { //使用代理 string text = "子线程执行,线程ID:" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n"; SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); i++; } private void SetText(string text) { lblSubThread.Text += text; }
1、当启动此计时器后,会在下方子线程ID列表中显示子线程ID,并且和主线程ID不相同

2、当单击主线程暂停5秒后,子线程会一直往下执行(界面上可能看不出来,不过通过在子线程输出文件的方式可以很方便的看出来)
3、在子进程的事件中暂停5秒不会导致主窗口无响应
4、在子线程事件中每次给线程静态变量加一,再点击线程静态变量值得到的值还是0(不会改变主窗口中的线程静态变量)