找回密码
 立即注册
首页 业界区 业界 深入浅出多线程系列之三:线程池

深入浅出多线程系列之三:线程池

羔迪 2025-5-29 15:46:31
线程池:

每一个线程默认会被分配1MB的内存,在C#中,这些都是实打实的分配的,当一个线程启动的时候,为了分配临时堆栈大约需要花费几百微秒的时间。

线程池通过循环利用线程可以让你更高效的利用线程。

 

线程池就像外包的劳务队一样,有任务给他们,他们会管理劳务工的一切,你不需要去花时间去找单个劳务工,然后完成任务就解雇她,

对劳务队而言,劳务工完成了你的这个任务,还是会回到自己的团队中的,劳务工的管理也不需要你去负责,因为这由劳务队处理了,

如果任务太多了,劳务队会自己招一个劳务工,如果还不够就继续招,但是如果任务比较少,而劳务工又比较多的话,对不起,劳务队的管理人员就会解雇一部分劳务工了。

 

有很多方法可以进入线程池:


       
  •     借助Task Parallel Library(framework 4.0)   
  •     调用ThreadPool.QueueUserWorkItem   
  •     借助异步委托。   
  •     借助BackgroundWorker.。 
下面的一些构造间接的使用了线程池:

       
  •     WCF,Remoting,Asp.net, asmx web services应用程序。   
  •     System.Timers.Timer 和 System.Threading.Timer.   
  •     framework的一些异步方法,例如WebClient 类,和大部分BeginXXX方法。   
  •     PLINQ 
使用线程池的一些问题:

       
  •     不可以设置一个线程池线程的名字。   
  •     线程池线程全部都是后台线程。   
  •     阻塞一个线程池线程可能会触发创建一个新线程,除非你调用ThreadPool.SetMinThreads方法。

  

通过Thread.CurrentThread.IsThreadPoolThread属性可以查询一个线程是否是线程池线程。

 

实战ThreadPool

1:通过Task使用线程池:

        public static void MainThread()
        {
            Task task = Task.Factory.StartNew
                (() => DownloadString("http://www.google.com"));

            //DoSomething
            string result = task.Result;
        }

        static string DownloadString(string uri)
        {
            using (var wc = new System.Net.WebClient())
                return wc.DownloadString(uri);
        }

 当查询task.Result的时候线程阻塞,等待task返回Result。

 

2:通过ThreadPool.QueueUserWorkItem

        public static void MainThread()
        {
            ThreadPool.QueueUserWorkItem(Go);
            ThreadPool.QueueUserWorkItem(Go, 123);
            
            Console.ReadLine();
        }

        static void Go(object data)
        {
            Console.WriteLine("Hello from the thread pool! " + data);
        }
Output:

Hello from the thread pool!

Hello from the thread pool! 123

 

3:借助委托的BeginXXX方法:

        public static void MainThread()
        {
            Func method = Work;
            method.BeginInvoke("test", Done, method);
        }

        static int Work(string s) { return s.Length; }

        static void Done(IAsyncResult cookie)
        {
            var target = (Func)cookie.AsyncState;
            int result = target.EndInvoke(cookie);
1.jpg
            Console.WriteLine("String length is:" + result);
        }
在这里将method当作参数进行传递后,在cookie的AsyncState中就可以使用传递的method了,

因为cookie.AsyncState类型是object,所以需要进行转换,然后调用EndInvoke方法来获取结果。

 

参考资料:
http://www.albahari.com/threading/
CLR Via C# 3.0
出处:http://www.cnblogs.com/LoveJenny/    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册