使用ThreadPool代替Thread
线程的空间开销
- 线程内核对象。包含上下文信息。32位系统占用700字节
- 线程环境块。包括线程的异常处理链。32位系统占用4KB
- 用户模式栈。保存方法的参数、局部变量和返回值
- 内核模式栈。调用操作系统的内核模式函数时,系统会将函数参数从用户模式栈复制到内核模式栈。32位系统占用12KB
线程的时间开销
- 创建时,系统相继初始化上述内存空间
- CLR加载DLL到DLLMain方法,并传送连接标志
- 线程上下文切换
- 进入内核模式
- 将上下文信息保存到正在执行的线程内核对象上
- 系统获取一个Spinlock,并确定下一个要执行的线程。释放Spinlock。如果下一个线程不在同一个进程,则需要进行虚拟地址交换
- 从将被执行的线程内核对象上载入上下文信息
- 离开内核模式
使用线程池,CLR不会销毁这个线程,而是会保留这个线程一段时间。
using System; using System.Diagnostics; using System.Threading; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var p = new Program(); Stopwatch sw = new Stopwatch(); sw.Start(); p.Thread(); sw.Stop(); Console.WriteLine(sw.ElapsedTicks); sw.Restart(); p.Pool(); sw.Stop(); Console.WriteLine(sw.ElapsedTicks); Console.ReadKey(); } void Thread() { for (int i = 0; i < 10; i++) { var worker = new Thread(() => { //Console.WriteLine("Thread Do"); }); worker.Start(); } } void Pool() { for (int i = 0; i < 10; i++) { ThreadPool.QueueUserWorkItem(state => { //Console.WriteLine("Pool Do"); }); } } } }