ThreadPool(线程池) in .Net
本文来自:http://rickie.cnblogs.com/archive/2004/11/23/67275.html
在多线程的程序中,经常会出现两种情况。一种情况下,应用程序中的线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应;而另外一种情况则是线程平常都处于休眠状态,只是周期性地被唤醒。这里分析及介绍.Net Framework中ThreadPool class来对付第一种情况,相应地也会谈到QueueUserWorkItem方法和WaitCallback委托。而使用Timer(System.Threading.Timer or System.Windows.Forms.Timer)来对付第二种情况,可以参考《System.Threading.Timer类的TimerCallback 委托》。
1. ThreadPool介绍(From MSDN)
ThreadPool class提供了一个线程池,该线程池可用于发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。线程池允许在后台运行多个工作,而不需要为每个任务频繁地创建和销毁单独的线程,从而减少了开销。
线程池通过为应用程序提供一个由系统管理的辅助线程池使您可以更为有效地使用线程。一个线程监视排到线程池的若干个等待操作的状态。当一个等待操作完成时,线程池中的一个辅助线程就会执行对应的回调函数。
也可以将与等待操作不相关的工作项排列到线程池。若要请求由线程池中的一个线程来处理工作项,请调用 QueueUserWorkItem 方法。此方法将对将被从线程池中选定的线程调用的方法或委托的引用用作参数。一个工作项排入队列后就无法再取消它。
计时器(System.Threading.Timer)队列中的计时器以及已注册的等待操作也使用线程池。它们的回调函数也会排列到线程池。关于这部分的内容,可以参考《System.Threading.Timer类的TimerCallback 委托》。
线程池在首次创建 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: Proper Threading in Winforms .Net, written by Shawn Cicoria,并附有Source code。
在上述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
2, Shawn Cicoria, Proper Threading in Winforms .Net, http://www.codeproject.com/csharp/winformthreading.asp
ThreadPool(线程池) in .Net的更多相关文章
- ThreadPool线程池 小结
ThreadPool类提供一个线程池,该线程池可用于发送工作项.处理异步 I/O.代表其他线程等待以及处理计时器 线程池通过为应用程序提供一个由系统管理的辅助线程池使您可以更为有效地使用线程.一个线程 ...
- 转载【浅谈ThreadPool 线程池】
浅谈ThreadPool 线程池 http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html
- 【多线程】-ThreadPool线程池
ThreadPool介绍: Thread类是一个静态类,所有不存在实例化构造函数操作,直接可以调用其内所存在的方法. 微软官网给出的解释: 提供一个线程池,该线程池可用于执行任务.发送工作项.处理异步 ...
- .net 线程基础 ThreadPool 线程池
1. ThreadPool 线程池异步: //public static bool QueueUserWorkItem(WaitCallback callBack); //public static ...
- 浅谈ThreadPool 线程池(引用)
出自:http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html 浅谈ThreadPool 线程池 相关概念: 线程池可以看做容纳线程的 ...
- 多线程之旅(ThreadPool 线程池)
一.什么是ThreadPool 线程池(源码) 1.线程池顾名思义,有我们的系统创建一个容器装载着我们的线程,由CLR控制的所有AppDomain共享.线程池可用于执行任务.发送工作项.处理异步 I/ ...
- 多线程 ThreadPool线程池
简单说明一下: 线程池可以看做容纳线程的容器:一个应用程序最多只能有一个线程池:ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池: 每排入一个工作函数,就相 ...
- Delphi ThreadPool 线程池(Delphi2009以上版本适用)
http://blog.sina.com.cn/s/blog_6250a9df0101kref.html 在网上查找Delphi线程池,结果发现寥寥无几. 看了半天源代码,弄得一头雾水,觉得不容易理解 ...
- ThreadPool 线程池的作用
相关概念: 线程池可以看做容纳线程的容器: 一个应用程序最多只能有一个线程池: ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池: 每排入一个工作函数,就相 ...
- 『Python』 ThreadPool 线程池模板
Python 的 简单多线程实现 用 dummy 模块 一句话就可以搞定,但需要对线程,队列做进一步的操作,最好自己写个线程池类来实现. Code: # coding:utf-8 # version: ...
随机推荐
- Hibernate(二)——POJO对象的操作
POJO对象其实就是我们的实体,这篇博客总结一下框架对POJO对象对应数据库主键的生成策略,和一些对POJO对象的简单增删改查的操作. 一,Hibernate框架中主键的生成策略有三种方式: 1,数 ...
- android jni ——Field & Method --> Accessing Field
现在我们知道了怎样使用native code访问简单的数据类型和引用参考类型(string,array),下面我们来介绍怎样让jni代码去访问java中的成员变量和成员函数,然后可以再jni中回调ja ...
- 使用<base target="_self" /> IE6 cann't open the Internet site 已终止操作
今日发现一个问题,我的网页需要用到<base target="_self" />,经测试IE8,9 谷歌 火狐全都正常,但是IE6 showModalDialog ...
- [HTML5] Level up -- Display
HTML5 Input type: Traditionally presentational tags, the i, b, em, and strong tags have been given n ...
- Chrome 开发者工具详解(4):Profiles 面板
概述 当前使用的Chrome最新版为54.0.2840.71,这个版本的Profiles面板比之前提供的功能更多也更强大,下面是该面板所包含的功能点: Record JavaScript CPU Pr ...
- ORA-14450
ORA-14450 attempt to access a transactional temp table already in use Cause: An attempt was made to ...
- 实战 Spring MVC接入支付宝即时到账 (部分代码)
下面就拿我项目中的部分代码来实践一下. 支付请求 首先,是提交表单 fund.jsp(这里我表单只需要用户填交易金额,其他的订单号之类的全部后台生成) <form id="deposi ...
- YUI之数组操作
YUI的构建数组,将类数组转换成真正的数组,从而可以使用数组的所有方法 数组构建 //真正的数组返回1,类数组返回2,其余的返回0 YArray.test = function (obj) { v ...
- 使用Promise规定来处理ajax请求的结果
ajax()返回结果是成功的,调用done()中的回调函数: 失败则调用fail()中的回调函数; always()的回调函数不管成功是否都会调用: 可以是使用then()函数代替done()和fai ...
- [转]设置MS Office Word for mac的默认显示比例
由于mac os的分辨率比较大,在PC上显示正常的word文档(显示比例100%),在mac下打开会很小,需要经常调整显示比例,如调到125%.130%或150%,可以通过下面方法来设置默认显示比例, ...