一、线程池简介

创建和销毁线程是一个要耗费大量时间的过程,太多的线程也会浪费内存资源,所以通过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. python 并行

    网址:http://www.parallelpython.com/ 下载模块[根据使用环境选择相应的下载版本]下载pp-1.6.4.4 .zip,注意不要下载md5 解压缩上面下载的文件:pp-1.6 ...

  2. mysql 远程登录 10038提示,无法连接

    mysql 默认使用端口3306 MYSQL服务器:WIN7 控制面板,WINDOWS防火墙--高级设置--入站规则--新建规则--端口--TCP-特定本地端口--3306--允许连接--下一步,至完 ...

  3. Leetcode6. Z 字形变换

    > 简洁易懂讲清原理,讲不清你来打我~ 输入字符串,按下右上下右上排列后输出字符串![在这里插入图片描述](https://img-blog.csdnimg.cn/4578280a7c1848c ...

  4. 微信小程序云开发-数据条件查询

    一.使用where条件查询 在.get()语句之前增加.where语句实现条件查询.  二.通过doc查询单条数据 1.使用doc来查询数据库中的单条数据 2.定义一个空对象,用来展示插叙到的单条数据 ...

  5. 【FATE】设置虚拟机固定IP以及免密登录

    一.前期准备 1.VMWare上新建三个Centos7的虚拟机 2.VMWare虚拟机的三种联网方式 1.桥接模式 -- 桥接: 默认使用VMnet0 这一种联网方式最简单,在局域网内,你的主机是怎么 ...

  6. idea创建普通Web项目lib目录无法输出,tomcat不报错问题

    idea创建普通Web项目lib目录无法输出,tomcat不报错问题 idea版本:2021.2 tomcat版本:9.0.50 项目结构 创建一个普普通通的web项目,目录结构大概就是这样 . ├─ ...

  7. Windows协议 LDAP篇 - 组&OU

    LDAP搜索 LDAP查找 位操作 以userAccountControl为例,CN=User-Account-Control,CN=Schema,CN=Configuration,DC=muxue, ...

  8. SaToken学习笔记-04

    SaToken学习笔记-04 如果有问题,请点击:传送门 角色认证 在sa-token中,角色和权限可以独立验证 // 当前账号是否含有指定角色标识, 返回true或false StpUtil.has ...

  9. [开源]入坑Qt,我的第一个小程序:MD5计算器

    版权声明 --------- 本文仅在知乎与博客园发布.开发者为szx0427 MFC和Win32搞了好几年了,也算是懂了个皮毛,但是一直觉得用这两者开发软件都很麻烦,需要将大量的代码花费在UI等地方 ...

  10. 连通图与Tarjan算法

    引言 Tarjan算法是一个基于深度优先搜索的处理树上连通性问题的算法,可以解决,割边,割点,双连通,强连通等问题. 首先要明白Tarjan算法,首先要知道它能解决的问题的定义. 连通图 无向图 由双 ...