博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入浅出多线程系列之三:线程池
阅读量:7251 次
发布时间:2019-06-29

本文共 2024 字,大约阅读时间需要 6 分钟。

线程池:

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

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

 

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

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

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

 

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

  1. 借助Task Parallel Library(framework 4.0)
  2. 调用ThreadPool.QueueUserWorkItem
  3. 借助异步委托。
  4. 借助BackgroundWorker.
     

下面的一些构造间接的使用了线程池:

  1. WCF,Remoting,Asp.net, asmx web services应用程序。
  2. System.Timers.Timer  System.Threading.Timer.
  3. framework的一些异步方法,例如WebClient 类,和大部分BeginXXX方法。
  4. PLINQ 

使用线程池的一些问题:

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

  

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

 

实战ThreadPool

1:通过Task使用线程池:

        public
 
static
 
void
 MainThread()
        {
            Task
<
string
>
 task 
=
 Task.Factory.StartNew
<
string
>
                (() 
=>
 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
<
string
int
>
 method 
=
 Work;
            method.BeginInvoke(
"
test
"
, Done, method);
        }
        
static
 
int
 Work(
string
 s) { 
return
 s.Length; }
        
static
 
void
 Done(IAsyncResult cookie)
        {
            var target 
=
 (Func
<
string
int
>
)cookie.AsyncState;
            
int
 result 
=
 target.EndInvoke(cookie);
             Console.WriteLine(
"
String length is:
"
 
+
 result);
        }

在这里将method当作参数进行传递后,在cookie的AsyncState中就可以使用传递的method了,

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

本文转自LoveJenny博客园博客,原文链接:http://www.cnblogs.com/LoveJenny/archive/2011/05/22/2052561.html,如需转载请自行联系原作者
你可能感兴趣的文章
第10章节-Python3.5-Django路由分发
查看>>
排序三 直接插入排序
查看>>
输入输出流体系图
查看>>
玩转报表排名
查看>>
《函数响应式领域建模》读后感
查看>>
一入前端深似海,从此红尘是路人系列第四弹之未来前端路该何去何从
查看>>
java笔记--笔试中极容易出错的表达式的陷阱
查看>>
第140天:前端开发中浏览器兼容性问题总结(一)
查看>>
socket编程的select模型
查看>>
智能医疗的春天在哪里?
查看>>
Kali Linux 无线渗透测试入门指南 第二章 WLAN 和固有的不安全性
查看>>
MyExcel 2.1.2 版本发布,重要 Bug 修复
查看>>
广汽与蔚来达成合作,将共同投资12.8亿元创立新能源汽车公司
查看>>
量子力学,整合了三种自然相互作用力
查看>>
亚马逊新专利,让无人机运送充电器为电动车充电
查看>>
HTC将Viveport推向全球,这是要“反击”Valve的节奏?
查看>>
【深度学习不是犯罪】欧盟祭出最严数据保护法:专家解读 GDPR
查看>>
浅谈SQL Server 对于内存的管理
查看>>
喜报销发布V2.4,圣诞焕新装,新增“专项费用报销”审批,集成京东商城
查看>>
陈天奇团队新研究:自动优化深度学习工作负载
查看>>