简单的线程池

来源:互联网 发布:yurisa知乎 编辑:程序博客网 时间:2024/05/27 20:53

1.引言

使用ThreadStart与ParameterizedThreadStart建立新线程非常简单,但通过此方法建立的线程难于管理,若建立过多的线程反而会影响系统的性能。有见及此,.NET引入CLR线程池这个概念。CLR线程池并不会在CLR初始化的时候立刻建立线程,而是在应用程序要创建线程来执行任务时,线程池才初始化一个线程。线程的初始化与其他的线程一样。在完成任务以后,该线程不会自行销毁,而是以挂起的状态返回到线程池。直到应用程序再次向线程池发出请求时,线程池里挂起的线程就会再度激活执行任务。这样既节省了建立线程所造成的性能损耗,也可以让多个任务反复重用同一线程,从而在应用程序生存期内节约大量开销。线程池分为工作者线程(workerThreads)与I/O线程 (completionPortThreads) 两种,工作者线程是主要用作管理CLR内部对象的运作,I/O(Input/Output) 线程顾名思义是用于与外部系统交换信息。线程池的工作者线程一般有两种方式,一是QueueUserWorkItem() ,二是通过委托(参见上篇)。

2.QueueUserWorkItem

ThreadPool线程池中包含有两个静态方法可以直接启动工作者线程:一为 ThreadPool.QueueUserWorkItem(WaitCallback)二为 ThreadPool.QueueUserWorkItem(WaitCallback,Object) 先把WaitCallback委托指向一个带有Object参数的无返回值方法,再使用 ThreadPool.QueueUserWorkItem(WaitCallback) 就可以异步启动此方法,此时异步方法的参数被视为null 。
class Program    {        static void Main(string[] args)        {            //把CLR线程池的最大值设置为1000            ThreadPool.SetMaxThreads(1000, 1000);            //显示主线程启动时线程池信息            ThreadMessage("Start");            //启动工作者线程            ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncCallback));            Console.ReadKey();        }        static void AsyncCallback(object state)        {            Thread.Sleep(200);            ThreadMessage("AsyncCallback");            Console.WriteLine("Async thread do work!");        }        //显示线程现状        static void ThreadMessage(string data)        {            string message = string.Format("{0}\n  CurrentThreadId is {1}",                 data, Thread.CurrentThread.ManagedThreadId);            Console.WriteLine(message);        }    }
class Program    {        static void Main(string[] args)        {            //把线程池的最大值设置为1000            ThreadPool.SetMaxThreads(1000, 1000);            ThreadMessage("Start");            ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncCallback),"Hello Elva");            Console.ReadKey();        }        static void AsyncCallback(object state)        {            Thread.Sleep(200);            ThreadMessage("AsyncCallback");            string data = (string)state;            Console.WriteLine("Async thread do work!\n"+data);        }        //显示线程现状        static void ThreadMessage(string data)        {            string message = string.Format("{0}\n  CurrentThreadId is {1}",                 data, Thread.CurrentThread.ManagedThreadId);            Console.WriteLine(message);        }    }

3.结束

通过ThreadPool.QueueUserWorkItem启动工作者线程虽然是方便,但WaitCallback委托指向的必须是一个带有Object参数的无返回值方法,这无疑是一种限制。若方法需要有返回值,或者带有多个参数,这将多费周折。有见及此,.NET提供了另一种方式去建立工作者线程,那就是委托。
0 0