怎样使用C#中的线程池
2011-09-07 15:38
337 查看
(原文来自http://msdn2.microsoft.com/en-us/library/3dasc8as.aspx 微软MSDN社区,原文为英文)
一个线程池是一个可以完成一系列当前环境下任务的线程的集合,他能够释放主线程去执行新的异步任务
线程池常常被用在服务器的应用程序上,每一个进入的请求被分配给线程池中的一个线程,所以每个请求可以被异步的处理而不用绑定到主线程或者延迟后续的请求处理
一旦线程池中的一个线程完成了任务就会马上返回到等待线程的队列中,在这里线程可以被复用。这种复用能够避免应用程序创建新的线程的额外开销
线程池特别的有个线程的最大值,如果所有的线程都是忙碌的。附加的任务会被放置到队列中知道有线程完成任务可以来执行这些任务
你可以实现你自己的线程池,但是使用.net framework提供的ThreadPool Class会更加简单
下面的是一个利用.NET Framework threadPool计算费波拉契数列的例子,每个费波拉契的结果被一个费波拉契的类所表示,这个类提供了一个方法——ThreadPoolCallBack,这个方法用来执行计算操作,一个object代表每个费波拉契对象的值被创建。这个方法被传递到ThreadPool的QueueUserWorkItem中,这个方法用来分配可用的线程来执行方法
因为每个费波拉契对象被赋予一个随机数来计算结果,而且10个线程都在争用CPU时间,所以我们没有办法事先知道完成所有10个线程所要花费的时间。这就是为什么每个费波拉契对象在构造函数中都会分配一个ManualResetEvent对象,用来标志计算完成,这个对象用来让主线程使用WaiAll方法阻塞操作直到所有10个线程都完成计算。然后由主线程显示结果
一个线程池是一个可以完成一系列当前环境下任务的线程的集合,他能够释放主线程去执行新的异步任务
线程池常常被用在服务器的应用程序上,每一个进入的请求被分配给线程池中的一个线程,所以每个请求可以被异步的处理而不用绑定到主线程或者延迟后续的请求处理
一旦线程池中的一个线程完成了任务就会马上返回到等待线程的队列中,在这里线程可以被复用。这种复用能够避免应用程序创建新的线程的额外开销
线程池特别的有个线程的最大值,如果所有的线程都是忙碌的。附加的任务会被放置到队列中知道有线程完成任务可以来执行这些任务
你可以实现你自己的线程池,但是使用.net framework提供的ThreadPool Class会更加简单
下面的是一个利用.NET Framework threadPool计算费波拉契数列的例子,每个费波拉契的结果被一个费波拉契的类所表示,这个类提供了一个方法——ThreadPoolCallBack,这个方法用来执行计算操作,一个object代表每个费波拉契对象的值被创建。这个方法被传递到ThreadPool的QueueUserWorkItem中,这个方法用来分配可用的线程来执行方法
因为每个费波拉契对象被赋予一个随机数来计算结果,而且10个线程都在争用CPU时间,所以我们没有办法事先知道完成所有10个线程所要花费的时间。这就是为什么每个费波拉契对象在构造函数中都会分配一个ManualResetEvent对象,用来标志计算完成,这个对象用来让主线程使用WaiAll方法阻塞操作直到所有10个线程都完成计算。然后由主线程显示结果
using System; using System.Threading; public class Fibonacci { public Fibonacci(int n, ManualResetEvent doneEvent) { _n = n; _doneEvent = doneEvent; } // Wrapper method for use with thread pool. public void ThreadPoolCallback(Object threadContext) { int threadIndex = (int)threadContext; Console.WriteLine("thread {0} started...", threadIndex); _fibOfN = Calculate(_n); Console.WriteLine("thread {0} result calculated...", threadIndex); _doneEvent.Set(); } // Recursive method that calculates the Nth Fibonacci number. public int Calculate(int n) { if (n <= 1) { return n; } return Calculate(n - 1) + Calculate(n - 2); } public int N { get { return _n; } } private int _n; public int FibOfN { get { return _fibOfN; } } private int _fibOfN; private ManualResetEvent _doneEvent; } public class ThreadPoolExample { static void Main() { const int FibonacciCalculations = 10; // One event is used for each Fibonacci object ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations]; Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations]; Random r = new Random(); // 开始使用线程池 Console.WriteLine("launching {0} tasks...", FibonacciCalculations); for (int i = 0; i < FibonacciCalculations; i++) { doneEvents[i] = new ManualResetEvent(false); Fibonacci f = new Fibonacci(r.Next(20, 40), doneEvents[i]); fibArray[i] = f; ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i); } // 等待线程池中所有计算完成 WaitHandle.WaitAll(doneEvents); Console.WriteLine("All calculations are complete."); // Display the results... for (int i = 0; i < FibonacciCalculations; i++) { Fibonacci f = fibArray[i]; Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN); } } }
相关文章推荐
- 怎样使用C#调用exe的应用程序
- C#使用线程池创建线程
- C# 线程池的使用
- 怎样使用C# 制作串口连接软件
- 【初识C#】怎样使用C#命令行编译器csc.exe编译Hello World 程序
- c# ThreadPool 线程池的使用
- C#简单使用线程池
- 关于C#线程,线程池和并行运算的简单使用和对比
- ASP.NET中使用Razor语法(C#)怎样获取当前浏览器的cookie
- 怎样在前端Javascript中调用C#方法(3)使用特性Attribute
- c#--怎样使用c#中的indexof和substring方法
- 【初识C#】怎样使用C#命令行编译器csc.exe编译Hello World 程序 (转)
- CLR via C# 读书笔记 1-1 何时使用线程或者线程池
- C#怎样在DataTable中使用linq查询
- C#中使用多线程编程之线程池
- [转]在C#中使用托管资源和非托管资源的区别,以及怎样手动释放非托管资源:
- 怎样获取一组汉字的拼音首字母(使用C#)
- 怎样使用C#添加计算机帐户并启用帐户
- c# 线程池中使用AutoResetEvent(事件)
- C#的pictureBox怎样使用多张图片简单切换