一、线程池简介

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

    文件是数据源的一种,最主要的作用是保存数据.在操作系统中,为了统一对各种硬件的操作,简化接口,不同的硬件设备也都被看成一个文件.对这些文件的操作,等同于对磁盘上普通文件的操作.例如: 通常把显示器称为 ...

  2. asp.net 读取 connectionStrings

    connectionStrings 在vs.net 2005 beta 2开始,如果你在web.config中使用了数据库连接字符串的配置,那么应该按如下的方法去写: <connectionSt ...

  3. 重拾javaweb(假期后第一次web测试)

    上学期通过十六周的时间,完成了javaweb的项目实践,其中包括很多次的练习以及测试.寒假时间大多用来挥霍,并没有对这些知识进行复习以及进一步的学习,所以在这场考试中,最终以八分的可怜成绩收尾,实在过 ...

  4. JProfiler监控java应用使用情况,故障情况分析

    1.软件部署(java环境已提前准备) 服务器:centos7.4 https://download-gcdn.ej-technologies.com/jprofiler/jprofiler_linu ...

  5. [刘阳Java]_Spring入门_第1讲

    Spring框架在企业中的使用非常多,优势明显.所以学好Spring框架肯定不言而喻.今天我们给大家介绍Spring的入门 1. 对于初学者来说我们要学习Spring框架中的哪些技术,这个有必要了解一 ...

  6. AgileTC linux部署

    简介 AgileTC是一套敏捷的测试用例管理平台,支持测试用例管理.执行计划管理.进度计算.多人实时协同等能力,方便测试人员对用例进行管理和沉淀.产品以脑图方式编辑可快速上手,用例关联需求形成流程闭环 ...

  7. python -- 结构数据类型(列表、元组、集合、字典)

    一.列表 列表表示一组有序的元素,这些元素可以是数字.字符串,也可以是另一个列表. # ----------------------------------------# 列表(list):一组有序的 ...

  8. [考试总结]noip模拟21

    中位数要排序!!!!!! 中位数要排序!!!!!! 中位数要排序!!!!!! 中位数要排序!!!!!! 中位数要排序!!!!!! 分差不加绝对值!!!! 分差不加绝对值!!!! 分差不加绝对值!!!! ...

  9. 解决proto文件生成pb文件时提示(e.g."message")的问题

    原因:格式不支持 解决办法:去下个notepad,打开方式选择notepad,文件属性的只读取消掉 打开后会发现最下面显示了文件的格式是unix,utf-8 右键红框处,选择转换为windows格式, ...

  10. 用好Git stash,助你事半功倍

    git stash: 用法:git stash list [<选项>] 或:git stash show [<选项>] [<stash>] 或:git stash ...