在C#中存在3种经常使用的 Timer :服务器
这个 Timer 是单线程的,也就是说只要它运行,其余线程就要等着。多线程
这个 Timer 有以下特色:函数
从上面的第一个特色能够得知,该 Timer 会形成 WinForm UI 假死,所以若是须要定时处理大量计算或者大量IO操做的任务,不建议使用该 Timer ,接下来咱们看一个例子体会一下在IO操做的状况下出现的假死状况:this
咱们在Form中放入两个Button 一个Lable和一个Timerspa
private void Button_Click(object sender, EventArgs e) { timer.Interval = 1000; timer.Tick += Timer_Tick; timer.Start(); } private void Timer_Tick(object sender, EventArgs e) { for (int i = 0; i < 10000; i++) { File.AppendAllText(Directory.GetCurrentDirectory()+"test.txt", i.ToString()); this.label_output.Text = "当前操做:插入数字" + i; } }
咱们单击计算按钮,咱们会发现WinForm出现了假死(没法移动窗口、按钮没法点击等)操作系统
该 Timer 是基于服务器的计时器,是为在多线程环境中用于辅助线程而设计的,能够在线程间移动来处理引起的 Elapsed 事件,比上一个计时器更加精确。线程
该 Timer 有以下特色:设计
一样咱们经过代码来看一下该 Timer 计时器怎么使用:code
System.Timers.Timer timersTimer = new System.Timers.Timer(); private void Button_Click(object sender, EventArgs e) { timersTimer.Interval = 1000; timersTimer.Enabled = true; timersTimer.Elapsed += TimersTimer_Elapsed; timersTimer.Start(); } private void TimersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { for (int i = 0; i < 10000; i++) { this.BeginInvoke(new Action(() => { this.label_output.Text="当前时间:"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); }), null); } } private void Button1_Click(object sender, EventArgs e) { timersTimer.Stop(); }
运行上面代码,会发现WinForm界面假死的状况消失了。orm
该 Timer 一样也是一个多线程的计时器,它有以下特色:
咱们来看一下代码(在控制台应用程序中输入如下代码):
static System.Threading.Timer threadingTimer; static int numSum = 0; static void Main(string[] args) { threadingTimer = new System.Threading.Timer(new System.Threading.TimerCallback(threadingTimer_Elapsed), null, 0, 1000); Console.Read(); } private static void threadingTimer_Elapsed(object state) { for (int i = 0; i < 10000; i++) { numSum++; Console.WriteLine("输出数字:"+i); } if (numSum > 10000) { threadingTimer.Dispose(); Console.WriteLine("结束"); } }
注意:当咱们再也不须要多线程Timer计时器的时候,咱们能够调用 Dispose 方法释放所占有的资源。可是由于Timer计时器是按线程池线程来安排回调执行的,所以回调可能发生在 Dispose方法的重载被调用以后,因此咱们可使用可以使用 Dispose(WaitHandle) 方法等待全部回掉完成。