开发手册 欢迎您!
软件开发者资料库

.NET(C#) ThreadPool线程池的使用总结

使用线程池,可以通过向应用程序提供由系统管理的工作线程池,来更有效地使用线程。托管线程池中的线程是后台线程。 其 IsBackground 属性为 true。线程池可以减少资源损耗。重用线程、控制线程数量,减少线程创建和切换所带来的开销。提高响应速度。可直接使用线程池中空闲的线程,而不必等待线程的创建。方便管理线程。本文主要介绍.NET(C#)中 ThreadPool线程池的使用,以及相关的示例代码。

1、查看线程池的最大线程数和最小线程数

ThreadPool.GetMaxThreads()方法检索可以同时处于活动状态的线程池请求的数目。所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。ThreadPool.GetMinThreads()方法检索线程池在新请求预测中维护的空闲线程数。workerThreads是线程池中辅助线程的最大数目。completionPortThreads是线程池中异步 I/O 线程的最大数目 线程过少可能无法实现可用资源的最优利用,而线程过多则可能增加资源争用。

using System; using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading; namespace ConsoleApplication{    class Program    {        static void Main(string[] args)        {            Console.WriteLine("----------线程池开始,线程ID是{0}-----------------", Thread.CurrentThread.ManagedThreadId);            int workthread;            int iothread;            ThreadPool.GetMaxThreads(out workthread, out iothread);            Console.WriteLine("Max Work Thread:{0} Max I/O Thread:{1}", workthread, iothread);            ThreadPool.GetMinThreads(out workthread, out iothread);            Console.WriteLine("Mix Work Thread:{0} Mix I/O Thread:{1}", workthread, iothread);            Console.WriteLine("----------线程池结束,线程ID是{0}-----------------", Thread.CurrentThread.ManagedThreadId);            Console.ReadKey();        }    }}

2、设置线程池的最大线程数和最小线程数

ThreadPool.SetMaxThreads()设置可以同时处于活动状态的线程池的请求数目。 所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。ThreadPool.SetMinThreads()发出新的请求时,在切换到管理线程创建和销毁的算法之前设置线程池按需创建的线程的最小数量。workerThreads是线程池中辅助线程的最大数目。completionPortThreads是线程池中异步 I/O 默认情况下,最小线程数设置为系统上的处理器数。 可以使用 SetMinThreads 方法来增加最小线程数。 但是,不必要地增加这些值可能导致性能问题。 如果在同一时间开始太多的任务,则所有任务均可能会很慢。 在大多数情况下,线程池可通过其自身用于分配线程的算法来更好地执行。 将最小值减小到小于处理器数量也可能会影响性能。

using System; using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading; namespace ConsoleApplication{    class Program    {        static void Main(string[] args)        {           Console.WriteLine("----------线程池开始,线程ID是{0}   -----------------", Thread.CurrentThread.ManagedThreadId);              int workthread = 8;           int iothread = 8;              ThreadPool.SetMaxThreads(workthread, iothread);           Console.WriteLine("Max Work Thread:{0} Max I/O Thread:{1}",    workthread, iothread);           ThreadPool.SetMinThreads(workthread, iothread);           Console.WriteLine("Mix Work Thread:{0} Mix I/O Thread:{1}",    workthread, iothread);              Console.WriteLine("----------线程池结束,线程ID是{0}   -----------------", Thread.CurrentThread.ManagedThreadId);           Console.ReadKey();        }    }}

3、ThreadPool的使用示例

调用 QueueUserWorkItem 方法以将方法排队以便在线程池线程上执行。 ThreadPool线程池会自动回收。一些复杂的并发操作,可以通过ManualResetEvent信号量等来实现。

using System; using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading; namespace ConsoleApplication{    class Program    {        const int cycleNum = 10;        static int cnt = 10;        static ManualResetEvent mrEvent = new ManualResetEvent(false);        static void Main(string[] args)        {            for (int i = 1; i <= cycleNum; i++)            {                ThreadPool.QueueUserWorkItem(new WaitCallback(TaskFunc), i    .ToString());            }                Console.WriteLine("mrEvent.WaitOne() Begin");            mrEvent.WaitOne();            Console.WriteLine("mrEvent.WaitOne() End");            Console.ReadKey();        }        public static void TaskFunc(object obj)        {            cnt -= 1;            Console.WriteLine(string.Format("{0}:第{1}个线程", DateTime    .Now.ToString(), obj.ToString()));            //获取正在运行的线程            Thread thread = Thread.CurrentThread;            //获取当前线程的唯一标识符            int id = thread.ManagedThreadId;            //获取当前线程的状态            System.Threading.ThreadState state = thread.ThreadState;            //获取当前线程的优先级            ThreadPriority priority = thread.Priority;            string strMsg = string.Format("Thread ID:{0}\n" + "Thread Name    :{1}\n" +                "Thread State:{2}\n" + "Thread Priority:{3}\n", id, thread    .Name,                state, priority);            Console.WriteLine(strMsg);            Thread.Sleep(100);            if (cnt == 0)            {                mrEvent.Set();            }        }            }}