首先,共享一个C++版本的精确到1毫秒的计时类,下载地点:https://pan.baidu.com/s/1s2hN6hg9GvPViw4JT6YsDw
在C#里此刻有3个Timer类:
System.Windows.Forms.Timer
System.Threading.Timer
System.Timers.Timer
这三个Timer我想大家对System.Windows.Forms.Timer已经很熟悉了,独一我要说的就是这个Timer在激发Timer.Tick事件的时候,事件的措置惩罚惩罚函数是在措施主线程上执行的,所以在WinForm上面用这个Timer很便利,因为在From上的所有控件都是在措施主线程上创建的,那么在Tick的措置惩罚惩罚函数中可以对Form上的所有控件进行操纵,不会造成WinForm控件的线程安适问题。
1、Timer运行的核心都是System.Threading.ThreadPool
在这里要提到ThreadPool(线程池)是因为,System.Threading.Timer 和System.Timers.Timer运行的核心都是线程池,Timer每到间隔时间后就会激发响应事件,因此要申请线程来执行对应的响应函数,Timer将获取线程的事情都交给了线程池来打点,每到必然的时间后它就去报告线程池:“我此刻激发了个事件要运行对应的响应函数,麻烦你给我向操纵系统要个线程,申请交给你了,线程分配下来了你就运行我给你的响应函数,没分配下来先让响应函数在这儿排队(操纵系统线程期待行列队伍)”,动静已经通报给线程池了,Timer也就不管了,因为它还有其他的事要做(每隔一段时间它又要激发事件),至于提交的请求什么时候能够得到满足,要看线程池当前的状态:
1、如果线程池此刻有线程可用,那么申请顿时就可以得到满足,有线程可用又可以分为两种情况:
<1>线程池此刻有空闲线程,此刻顿时就可以用
<2>线程池原来此刻没有线程了,但是恰好申请达到的时候,有线程运行完毕释放了,那么申请就可以用别人释放的线程。
这两种情况情况就如同你去游乐园玩赛车,如果游乐园有10辆车,此刻有3小我私家在玩,那么还剩7辆车,你去了固然可以选一辆开。此外还有一种情况就是你达到游乐园前10辆车都在开,但是你运气很好,刚到游乐园就有人不玩了,正好你坐上去就可以接着开。
2、如果此刻线程池此刻没有线程可用,也分为两种情况:
<1>线程池现有线程数没有到达设置的最大事情线程数,那么隔半秒钟.net framework就会向操纵系统申请一个新的线程(为制止向线程分配不须要的仓库空间,线程池凭据必然的时间间隔创建新的空闲线程。该时间间隔目前为半秒,但它在 .NET Framework 的以后版本中可能会变动)。
<2>线程池现有事情线程数到达了设置的最大事情线程数,那么申请只有在期待行列队伍一直等下去,直到有线程执行完任务后被释放。
那么上面提到了线程池有最大事情线程数,其实还有最小空闲线程数,那么这两个关键字是什么意思呢:
1、最大事情线程数:实际上就是指的线程池能够向操纵系统申请的最大线程数,这个值在.net framework中有默认值,这个默认值是按照你计算机的配置来的,当人你可以用ThreadPool.GetMaxThreads返回线程池当前最大事情线程数,你也可以同ThreadPool.SetMaxThreads设置线程池当前最大事情线程数。
2、最小空闲线程数:是指在措施开始后,线程池就默认向操纵系统要最小空闲线程数个线程,此外这也是线程池维护的空闲线程数(如果线程池最小空闲线程数为3,当前因为一些线程执行完任务被释放,线程池此刻实际上有10个空闲线程,那么线程池会让操纵系统释放多余的7个线程,而只维持3个空闲线程供措施使用),因为上面说了,在执行措施的时候在要线程池申请线程有半秒的延迟时间,这也会影响措施的性能,所以操作独霸好这个值很重要,用样你可以用ThreadPool.GetMinThreads返回线程池当前最小空闲线程数,你也可以同ThreadPool.SetMinThreads设置线程池当前最小空闲线程数。
下面是我给的例子,这个例子让线程池申请800个线程,此中设置最大事情线程数为500,800个线程任务每个都要执行100000000毫秒目的是让线程不会释放,并且让用户选择,是否预先申请500个空闲线程免受那半秒钟的延迟时间,其功效可想而知当线程申请到500的时候,线程池到达了最大事情线程数,残剩的300个申请进入漫长的期待时间:
代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://>/*************************************************** * 项目:测试线程池 * 描述:验证线程池的最大事情线程数和最小空闲线程数 * 作者:@PowerCoder * 日期:2010-2-22 ***************************************************/ using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace ConsoleApplication1 { class Program { static int i=1; static int MaxThreadCount = 800; static void OutPut(object obj) { Console.Write("\r申请了:{0}个事情线程",i); i++; Thread.Sleep(100000000);//设置一个很大的期待时间,让每个申请的线程都一直执行 } static void Main(string[] args) { int j; Console.Write("是否先申请500个空闲线程以保证前500个线程在线程池中开始就有线程用(Y/N)?");//如果这里选择N,那么前两个任务是用的线程池默认空闲线程(可以用ThreadPool.GetMinThreads得到系统默认最小空闲线程数为2)申请当即得到满足,然而由于每个线程期待时间非常多半不会释放当前本身持有的线程,因此线程池中已无空闲线程所用,后面的任务需要在线程池中申请新的线程,那么新申请的每个线程在线程池中都要隔半秒摆布的时间才华得到申请(原因请见下面的注释) string key = Console.ReadLine(); if(key.ToLower()=="y") ThreadPool.SetMinThreads(500, 10);//设置最大空闲线程为500,就仿佛我报告系统给我预先筹备500个线程我来了就直接用,因为这样就不用现去申请了,在线程池中每申请一个新的线程.NET Framework 会布置一个间隔时间,目前是半秒,以后的版本MS有可能会改 int a, b; ThreadPool.GetMaxThreads(out a,out b); Console.WriteLine("线程池默认最大事情线程数:" + a.ToString() + " 默认最大异步 I/O 线程数:" + b.ToString()); Console.WriteLine("需要向系统申请" + MaxThreadCount.ToString()+"个事情线程"); for (j = 0; j <= MaxThreadCount-1; j++)//由于ThreadPool.GetMaxThreads返回的默认最大事情线程数为500(这个值要按照你计算机的配置来决定),那么向线程池申请大于500个线程的时候,500之后的线程会进入线程池的期待行列队伍,期待前面500个线程某个线程执行完后来唤醒期待行列队伍的某个线程 { ThreadPool.QueueUserWorkItem(new WaitCallback(OutPut)); Thread.Sleep(10); } Console.ReadLine(); } } }
2、System.Threading.Timer