ThreadPool(线程池)in .Net

在多线程的程序中,经常会出现两种情况。一种情况下,应用程序中的线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应;而另外一种情况则是线程平常都处于休眠状态,只是周期性地被唤醒。这里分析及介绍.Net Framework中ThreadPool class来对付第一种情况,相应地也会谈到QueueUserWorkItem方法和WaitCallback委托。而使用Timer(System.Threading.Timer or System.Windows.Forms.Timer)来对付第二种情况,可以参考《》。

1. ThreadPool介绍(From MSDN)

ThreadPool class提供了一个线程池,该线程池可用于发送工作项、处理异步I/O、代表其他线程等待以及处理计时器。线程池允许在后台运行多个工作,而不需要为每个任务频繁地创建和销毁单独的线程,从而减少了开销。

线程池通过为应用程序提供一个由系统管理的辅助线程池使您可以更为有效地使用线程。一个线程监视排到线程池的若干个等待操作的状态。当一个等待操作完成时,线程池中的一个辅助线程就会执行对应的回调函数。

也可以将与等待操作不相关的工作项排列到线程池。若要请求由线程池中的一个线程来处理工作项,请调用QueueUserWorkItem方法。此方法将对将被从线程池中选定的线程调用的方法或委托的引用用作参数。一个工作项排入队列后就无法再取消它。

计时器(System.Threading.Timer)队列中的计时器以及已注册的等待操作也使用线程池。它们的回调函数也会排列到线程池。关于这部分的内容,可以参考《》。

线程池在首次创建ThreadPool类的实例时被创建。线程池具有每个可用处理器25个线程的默认限制,这可以使用mscoree.h文件中定义的CorSetMaxThreads来更改。每个线程使用默认的堆栈大小并按照默认的优先级运行。每个进程只能具有一个操作系统线程池。

2. ThreadPool.QueueUserWorkItem方法

QueueUserWorkItem方法将指定的方法排入队列以便执行,并指定包含该方法所用数据的对象,此方法在有线程池线程变得可用时执行。

public static bool QueueUserWorkItem(

WaitCallback callBack,

object state

);

如果将方法成功排入队列,则为true;否则为false。如果排入队列的方法仅需要单个数据项,可以将数据项强制转换为类型Object。如果该方法需要多个复杂数据,则必须定义包含这些数据的类。如果没有参数传入,则可以调用QueueUserWorkItem(WaitCallback callBack)重载。

ThreadPool提供的公共方法都是static方法,因此也不需要生成ThreadPool对象。通过QueueUserWorkItem方法在线程池中添加一个工作项目后,目前没有提供简单的方法取消。你不必建立咨监线程,只需要把相应的函数或方法依托WaitCallback委托传递给ThreadPool.QueueUserWorkItem()方法即可。而线程的创建、管理和运行等等都由系统自动完成,这就是ThreadPool的优点。

3. WaitCallback委托

WaitCallback委托声明线程池要执行的回调方法,回调方法的声明必须与WaitCallback委托声明具有相同的参数。

WaitCallback表示要在ThreadPool线程上执行的回调方法。创建委托,方法是将回调方法传递给WaitCallback构造函数。您的方法必须具有此处所显示的签名。通过将WaitCallback委托传递给ThreadPool.QueueUserWorkItem来将任务排入队列以便执行。您的回调方法将在某个线程池线程可用时执行。

如果要将信息传递给回调方法,请创建包含所需信息的对象,并在将任务排入队列以便执行时将它传递给QueueUserWorkItem。每次执行您的回调方法时,state参数都包含此对象。

通过将一个方法打包到WaitCallback委托中,然后将该委托传递给ThreadPool.QueueUserWorkItem静态方法,在线程池中对任务进行排队。

4. Demo application using ThreadPool class

codeproject.com上有一个不错的,并附有。

在上述Demo程序中,不仅提供了使用ThreadPool线程池的方法,而且还演示了Thread和ThreadStart委托的方法。

private void button1_Click(object sender, System.EventArgs e)

{

ShowProgressDelegate showProgress = new ShowProgressDelegate(ShowProgress);

int imsgs = 100;

//One Way... Using ThreadPool

if ( cbThreadPool.Checked )

{

object obj = new object[] { this, showProgress, imsgs };

WorkerClass wc = new WorkerClass();

bool rc = ThreadPool.QueueUserWorkItem( new WaitCallback (wc.RunProcess), obj);

EnableButton( ! rc );

}

else

{

//another way.. using straight threads

WorkerClass wc = new WorkerClass( this, showProgress, new object[] { imsgs } );

Thread t = new Thread( new ThreadStart(wc.RunProcess));

t.IsBackground = true; //make them a daemon - prevent thread callback issues

t.Start();

EnableButton ( false );

}

}

另外,上述Demo程序中还调用Windows form控件的BeginInvoke方法:在创建控件的基础句柄所在线程上,用指定的参数异步执行指定委托。BeginInvoke方法在不同的线程池线程上回调指定的委托,实际上就是发起后台的调用来放置一条消息到windows form的消息循环(message loop)中。

public IAsyncResult BeginInvoke(Delegate, object[]);

***

Any questions about the demo application, please leave message below. I will try to explain it. Thanks.

References:

1, MSDN, ThreadPool, QueueUserWorkItem and WaitCallback

mysql threadpool_ThreadPool(线程池) in .Net相关推荐

  1. 蚂蚁花呗1-5面(高级):分布式+MySQL+HashMap+线程池+MQ+Redis

    24小时新鲜出炉的阿里面经,已拿下offer,趁热和大家分享,依旧是咱们原来的文章风格,省略各种前情提要和勾搭过程,直击面试拷问细节. 蚂蚁花呗一面:技术面 线程池的工作原理,几个重要参数? 给了具体 ...

  2. mysql 关闭线程池_线程池安全的关闭方式

    对于一些定时任务或者网络请求服务将会使用线程池,当应用停机时需要正确安全的关闭线程池,如果处理不当,可能造成数据丢失,业务请求结果不正确等问题. 关闭线程池我们可以选择什么都不做,JVM 关闭时自然的 ...

  3. 关于MySQL线程池,这也许是目前最全面的实用帖!

    作者介绍 张秀云,网名飞鸿无痕,现任职于腾讯,负责腾讯金融数据库的运维和优化工作.2007年开始从事运维方面的工作,经历过网络管理员.Linux运维工程师.DBA.分布式存储运维等多个职位.对Linu ...

  4. 关于MySQL线程池,这也许是目前最全面的实用帖!(转载)

    关于MySQL线程池,这也许是目前最全面的实用帖! 最近出现多次由于上层组件异常导致DB雪崩的情况,笔者将部分监控DB启用了线程池功能,在使用线程池的过程中不断深入学习的同时,也遇到了不少问题. 本文 ...

  5. 线程池的开源实现(mariadb和percona版本)

    2019独角兽企业重金招聘Python工程师标准>>> 一."Thread pool in MariaDB 5.5" 线程池解决的问题: 传统mysql使用一个线 ...

  6. mysql清理连接数缓存,MySQL连接池、线程缓存、线程池的区别

    1. MySQL连接池 连接池通常实现在client端,是指应用(客户端)预先创建一定的连接,利用这些连接服务于客户端所有的DB请求.如果某一个时刻,空闲的连接数小于DB的请求数,则需要将请求排队,等 ...

  7. mysql 线程池源码模块_易语言Mysql线程池2.0模块源码

    易语言Mysql线程池2.0模块源码 易语言Mysql线程池2.0模块源码 系统结构:GetThis,初始化,关闭类线程,线程_测试,其他_附加文本,连接池初始化,取mysql句柄,释放mysql句柄 ...

  8. mysql连接池为何不用nio_MyCAT 在 Cobar 的基础上,完成了彻底的 NIO 通讯,并且合并了两个线程池...

    研读: 1.http://www.mycat.io <Mycat权威指南> 第 2 章 Mycat 前世今生: 浏览: 深度认识 Sharding-JDBC:做最轻量级的数据库中间层 - ...

  9. 两个线程同时从服务器接收消息_一文看懂I/O多路复用技术(mysql线程池)

    概述 当我们要编写一个echo服务器程序的时候,需要对用户从标准输入键入的交互命令做出响应.在这种情况下,服务器必须响应两个相互独立的I/O事件:1)网络客户端发起网络连接请求,2)用户在键盘上键入命 ...

最新文章

  1. 读书笔记之MySQL技术内幕
  2. 解决在ESXi的虚拟化环境中的FreeNAS里Jails插件无法被访问到的问题
  3. “城迷”:黑白梦与精神逃离
  4. PL/SQL Developer跑在Oracle 64位数据库上初始化错误
  5. Google Wave 的失败给现代实时协作办公的一个重大教训!
  6. 凸优化第九章无约束优化 9.1无约束优化问题
  7. Microsoft Excel 教程:如何在 Excel 中筛选区域或表中的数据?
  8. photoshop cs6 下载并安装教程
  9. PHP开发的一个搞笑段子手生成小程序
  10. 基于卷积神经网络的猫种类的识别
  11. php查找最高分最低分,​热播网剧评分最高8.6分,最低只有5.3分,你猜到哪部剧最低吗?...
  12. 福特FORD EDI需求分析
  13. 【论文阅读】Heterogeneous Graph Attention Network
  14. c语言双重性,C语言双重循环应用初探
  15. 微信支付快速生成签名sign
  16. 华擎主板bios设置图解_华擎主板设置BIOS的图解教程
  17. spring和servlet之间得关系
  18. 区块链未来三年内将广泛落地
  19. 智能家居Homekit解决方案
  20. input如何设置默认值

热门文章

  1. WebLogic的使用总结(一)
  2. WebLogic的使用总结(二)
  3. 十二张图,踹开消息队列的大门
  4. Linux系统安装教程(手把手教学)
  5. 滚珠丝杆高效测量方案
  6. count() 优化
  7. 用MATLAB仿真SCARA机器人,报错:未定义与 ‘char‘ 类型的输入参数相对应的函数 ‘Link‘
  8. POE技术原理及硬件实现
  9. wget下载ftp地址密码里有@符号如何解决
  10. 2022年高处吊篮安装拆卸工(建筑特殊工种)考试练习题模拟考试平台操作