一、线程池简介

创建和销毁线程是一个要耗费大量时间的过程,太多的线程也会浪费内存资源,所以通过Thread类来创建过多的线程反而有损于性能,为了改善这样的问题 ,.net中就引入了线程池。

线程池形象的表示就是存放应用程序中使用的线程的一个集合。

CLR初始化时,线程池中是没有线程的,在内部, 线程池维护了一个操作请求队列,当应用程序想执行一个异步操作时,就调用一个方法,就将一个任务放到线程池的队列中,线程池中代码从队列中提取任务,将这个任务委派给一个线程池线程去执行,当线程池线程完成任务时,线程不会被销毁,而是返回到线程池中,等待响应另一个请求。由于线程不被销毁, 这样就可以避免因为创建线程所产生的性能损失。

注意:通过线程池创建的线程默认为后台线程,优先级默认为Normal.

二、创建方法

public static bool QueueUserWorkItem (WaitCallback callBack);

public static bool QueueUserWorkItem(WaitCallback callback, Object state);

这两个方法向线程池的队列添加一个工作项(work item)以及一个可选的状态数据。

工作项其实就是由callback参数标识的一个方法,该方法将由线程池线程执行。

回调方法必须匹配System.Threading.WaitCallback委托类型,定义为:

public delegate void WaitCallback(Object state);

三、使用例子

(1)正常使用

 1 using System;
2 using System.Threading;
3
4 namespace ThreadPoolWorkerItem
5 {
6 class Program
7 {
8 static void Main(string[] args)
9 {
10 Console.WriteLine("Thread pool thread test...");
11 Console.WriteLine();
12 string myInfo = "The following is the thread info ontained in function Main";
13 PrintThreadInfo(myInfo);
14 Console.WriteLine();
15 ThreadPool.QueueUserWorkItem(AsyncMethod);
16 Console.ReadLine();
17
18 }
19 private static void PrintThreadInfo(string info)
20 {
21 Console.WriteLine(info);
22 Console.WriteLine($"ThreadId:{Thread.CurrentThread.ManagedThreadId}\nIsBackgroundThread:{Thread.CurrentThread.IsBackground}\nIsThreadPoolThread:{Thread.CurrentThread.IsThreadPoolThread}");
23 int workerThread = 0;
24 int ioThread = 0;
25 ThreadPool.GetMaxThreads(out workerThread, out ioThread);
26 Console.WriteLine($"MaxWorkerThread:{workerThread}\nMaxIoThread:{ioThread}");
27 int workerThreadAvailable = 0;
28 int ioThreadAvailable = 0;
29 ThreadPool.GetAvailableThreads(out workerThreadAvailable, out ioThreadAvailable);
30 Console.WriteLine($"AvailableWorkerThread:{workerThreadAvailable}\nAvailableIoThread:{ioThreadAvailable}");
31 }
32 private static void AsyncMethod(object state)
33 {
34 string myInfo = "The following is the thread info ontained in function AsyncMethod";
35 PrintThreadInfo(myInfo);
36 Thread.Sleep(3000);
37 Console.WriteLine("AsyncMethod done!");
38 }
39 }
40 }

运行结果如下:

(2)任务取消

  下面使用System.Threading.CancellationTokenSource对象来对任务进行取消操作。 

 1 using System;
2 using System.Threading;
3
4 namespace ThreadPoolWorkerItem
5 {
6 class Program
7 {
8 static void Main(string[] args)
9 {
10 Console.WriteLine("Thread pool thread test...");
11 Console.WriteLine();
12 //string myInfo = "The following is the thread info ontained in function Main";
13 //PrintThreadInfo(myInfo);
14 //Console.WriteLine();
15
16 CancellationTokenSource cts = new CancellationTokenSource();
17 ThreadPool.QueueUserWorkItem(AsyncMethod, cts.Token);
18
19 while(true)
20 {
21 string myLine = Console.ReadLine();
22 if(myLine == "quit")
23 {
24 break;
25 }
26 switch(myLine)
27 {
28 case "cancel":
29 Console.WriteLine("Cancel request from user...");
30 cts.Cancel();
31 break;
32 }
33 }
34
35 }
36 private static void PrintThreadInfo(string info)
37 {
38 Console.WriteLine(info);
39 Console.WriteLine($"ThreadId:{Thread.CurrentThread.ManagedThreadId}\nIsBackgroundThread:{Thread.CurrentThread.IsBackground}\nIsThreadPoolThread:{Thread.CurrentThread.IsThreadPoolThread}");
40 int workerThread = 0;
41 int ioThread = 0;
42 ThreadPool.GetMaxThreads(out workerThread, out ioThread);
43 Console.WriteLine($"MaxWorkerThread:{workerThread}\nMaxIoThread:{ioThread}");
44 int workerThreadAvailable = 0;
45 int ioThreadAvailable = 0;
46 ThreadPool.GetAvailableThreads(out workerThreadAvailable, out ioThreadAvailable);
47 Console.WriteLine($"AvailableWorkerThread:{workerThreadAvailable}\nAvailableIoThread:{ioThreadAvailable}");
48 }
49 private static void AsyncMethod(object state)
50 {
51 //string myInfo = "The following is the thread info ontained in function AsyncMethod";
52 //PrintThreadInfo(myInfo);
53 CancellationToken cltToken = (CancellationToken)state;
54 int myCountNumber = 100;
55 for (int i = 0; i < myCountNumber; i++)
56 {
57 Console.WriteLine(i);
58 if (cltToken.IsCancellationRequested)
59 {
60 Console.ForegroundColor = ConsoleColor.DarkRed;
61 Console.WriteLine($"Counting is cancelled. Current:{i} / Total:{myCountNumber}");
62 Console.ResetColor();
63 return;
64 }
65 Thread.Sleep(3000);
66
67 }
68 Console.WriteLine("Counting is done!");
69 }
70 }
71 }

运行结果如下:

C#多线程---线程池的工作者线程的更多相关文章

  1. Java多线程系列--“JUC线程池”01之 线程池架构

    概要 前面分别介绍了"Java多线程基础"."JUC原子类"和"JUC锁".本章介绍JUC的最后一部分的内容——线程池.内容包括:线程池架构 ...

  2. Java多线程系列--“JUC线程池”02之 线程池原理(一)

    概要 在上一章"Java多线程系列--“JUC线程池”01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析Th ...

  3. Java多线程系列--“JUC线程池”03之 线程池原理(二)

    概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...

  4. Java多线程系列--“JUC线程池”04之 线程池原理(三)

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3509960.html 本章介绍线程池的生命周期.在"Java多线程系列--“基础篇”01之 基 ...

  5. Java多线程系列--“JUC线程池”05之 线程池原理(四)

    概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...

  6. 【温故而知新-万花筒】C# 异步编程 逆变 协变 委托 事件 事件参数 迭代 线程、多线程、线程池、后台线程

    额基本脱离了2.0 3.5的时代了.在.net 4.0+ 时代.一切都是辣么简单! 参考文档: http://www.cnblogs.com/linzheng/archive/2012/04/11/2 ...

  7. C#线程篇---线程池如何管理线程(6完结篇)

    C#线程基础在前几篇博文中都介绍了,现在最后来挖掘一下线程池的管理机制,也算为这个线程基础做个完结. 我们现在都知道了,线程池线程分为工作者线程和I/O线程,他们是怎么管理的? 对于Microsoft ...

  8. 通过设置线程池的最小线程数来提高task的效率,SetMinThreads。

    http://www.cnblogs.com/Charltsing/p/taskpoolthread.html task默认对线程的调度是逐步增加的,连续多次运行并发线程,会提高占用的线程数,而等若干 ...

  9. 内存池、进程池、线程池介绍及线程池C++实现

    本文转载于:https://blog.csdn.net/ywcpig/article/details/52557080 内存池 平常我们使用new.malloc在堆区申请一块内存,但由于每次申请的内存 ...

随机推荐

  1. Java 8 Function 函数接口

    这篇文章属于 Java 8 教程(LTS)系列教程 在 Java 8 中,Function 接口是一个函数接口,它位于包 java.util.function 下. Function 接口中定义了一个 ...

  2. 整理最近用的Mongo查询语句

    背景 最近做了几个规则逻辑.用到mongo查询比较多,就是查询交易信息跑既定规则筛选出交易商户,使用聚合管道进行统计和取出简单处理后的数据,用SQL代替业务代码逻辑的判断. 方法 MongoDB聚合使 ...

  3. Scala学习——集合

    Scala集合 一.数组 package top.ruandb.scala.Course04 object ArrayApp { def main(args: Array[String]): Unit ...

  4. Junit测试用例配置Log4j

    用Junit测试非常方便,但有时我们想要看日志来方便排除,使用spring+log4j时,用Junit测试看日志很多人都不太会,即如何将Junit与log4j进行整合. 我也是研究了半天,才终于找到了 ...

  5. MySQL 8.x 新版本特性赶紧学!!Linux 服务器上安装 MySQL 8.x

    我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复[资料],即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板. 引言 ...

  6. 2019 Mac下安装运行Homestead环境

    为了能提高自己的价值,还是要坚持学习新东西才行.这不,从多学会一个PHP开发框架开始.在开始使用Laravel之前,很多"经验"告诉我要先安装Homestead,至于好处,大家可以 ...

  7. python基础之读取xml

    python怎么操作xml文件详细介绍链接:https://www.jb51.net/article/50812.htm 从结构上来说,xml很像常见的HTML超文本标记语言.不过超文本语言被设计用来 ...

  8. Python基础之subprocess

    前言 subprocess这个函数很好用,类似于控制台执行,功能很多,今天先介绍subprocess调用exe,并行调用两个或两个以上的exe. Subprocess调用exe 调用exe有几种方式, ...

  9. 第五篇--Chorme浏览器主页被篡改

    解决方法:关闭谷歌浏览器,右击桌面快捷方式,查看属性,然后将target后面的网址删掉.并且任务栏的google打开方式,最好也把流氓网址删掉.之后就正常了.

  10. Apollo mqtt 服务器搭建

    html { overflow-x: initial !important } :root { --bg-color: #ffffff; --text-color: #333333; --select ...