一、线程池简介

创建和销毁线程是一个要耗费大量时间的过程,太多的线程也会浪费内存资源,所以通过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. C语言:逻辑运算符||

    #include <stdio.h> //逻辑运算符||特点:左右两边的表达式先做左边,如果左边为1则右边不用执行,整个结果为1:如果左边为0,再执行右边: main() { int x= ...

  2. C语言:地址

    一切都是地址 C语言用变量来存储数据,用函数来定义一段可以重复使用的代码,它们最终都要放到内存中才能供 CPU 使用.数据和代码都以二进制的形式存储在内存中,计算机无法从格式上区分某块内存到底存储的是 ...

  3. DEV C++5.11编译没有结果提示

    点击"视图"菜单--选择"浮动报告 窗口"

  4. DataFrame的创建

    DataFrame的创建从Spark2.0以上版本开始,Spark使用全新的SparkSession接口替代Spark1.6中的SQLContext及HiveContext接口来实现其对数据加载.转换 ...

  5. 高校表白App-团队冲刺第三天

    今天要做什么 今天开站立会议的时候,忽然发觉在一个完整的App上好像是有一些引导页的,比如说在第一次使用App的时候,或者是在使用App的时候会出现新手指引操作. 做了什么 通过查阅资料来学习View ...

  6. 构建高效Presubmit卡点,落地测试左移最佳实践

    樊登有一节课讲的挺有意思,说中国有个组织叫绩效改进协会,专门研究用技控代替人控的事情.其用麦当劳来举例子,他说麦当劳其实招人标准很低,高中文凭就可以,但是培养出来的人,三五年之后,每一个都是大家争抢的 ...

  7. 在R中使用Keras和TensorFlow构建深度学习模型

    一.以TensorFlow为后端的Keras框架安装 #首先在ubuntu16.04中运行以下代码 sudo apt-get install libcurl4-openssl-dev libssl-d ...

  8. 第十三天 -- 如何用U盘重装系统Win10以及如何用VMware12安装Win10

    U盘制作启动盘 1.在电脑上插入U盘,关闭安全软件杀毒工具,然后打开装机吧U盘启动盘制作工具 2.选择刚插入的U盘,勾选上,点击一键制作启动U盘,制作前U盘数据必须转移备份: 3.选择格式化U盘,记得 ...

  9. 自学linux——19.TFTP服务器的搭建

    TFTP服务器的搭建 1.TFTP的认识 TFTP(Trivial File Transfer Protocol)简单文件传输协议,是一种基于UDP协议在客户端和服务器之间进行简单文件传输的协议,不需 ...

  10. 解决ModuleNotFoundError: No module named 'pip'问题

    Python学习遇到小问题:ModuleNotFoundError: No module named 'pip' 今天想要装一下第三方库exifread的时候发现cmd窗口下无法执行pip命令,想了想 ...