1 线程池概念
每当您启动一个线程时,都会花费几百微秒来组织新的私有局部变量堆栈。每个线程还消耗(默认情况下)大约1 MB的内存。线程池通过共享和回收线程来减少这些开销,从而允许在非常精细的级别上应用多线程,而不会降低性能。这在利用多核处理器以“分而治之”的方式并行执行计算密集型代码时非常有用。
线程池还限制了它将同时运行的工作线程总数。太多的活动线程用管理负担来限制操作系统,并使CPU缓存无效。一旦达到限制,作业将排队并仅在另一个作业完成时启动。这使得任意并发的应用程序成为可能,例如web服务器。
以下是进入线程池的多种方法:
- 通过Task并行库Task Parallel Library(TPL)(来自Framework 4.0)
- 通过调用ThreadPool.QueueUserWorkItem
- 通过异步委托(asynchronous delegates)
- 通过BackgroundWorker
1.1 线程池特点
- 线程池内的线程属于background thread
- 线程池内的线程不能设定线程名
- 我们可以通过Thread.CurrentThread.IsThreadPoolThread属性判断线程是否为线程池线程。
2 使用TPL创建线程池线程
可以使用Task.Factory.StartNew方法,举例:
static void Main() // The Task class is in System.Threading.Tasks
{
Task.Factory.StartNew (Go);
}
static void Go()
{
Console.WriteLine ("Hello from the thread pool!");
}
Task.Factory.StartNew返回一个Task对象,然后可以使用该对象监视任务-例如,可以通过调用其wait方法等待任务完成。
当您调用任务的Wait方法时,任何未处理的异常都会被方便地重新抛出到主机线程上。
这是与Thread类不一样的地方,即Task可以通过Wait()方法和Result属性获取把子线程的异常抛出到父线程。下面的Task<TResult>的例子:
static void Main()
{
// Start the task executing:
Task<string> task = Task.Factory.StartNew