本文来自: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的更多相关文章

  1. ThreadPool线程池 小结

    ThreadPool类提供一个线程池,该线程池可用于发送工作项.处理异步 I/O.代表其他线程等待以及处理计时器 线程池通过为应用程序提供一个由系统管理的辅助线程池使您可以更为有效地使用线程.一个线程 ...

  2. 转载【浅谈ThreadPool 线程池】

    浅谈ThreadPool 线程池 http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html

  3. 【多线程】-ThreadPool线程池

    ThreadPool介绍: Thread类是一个静态类,所有不存在实例化构造函数操作,直接可以调用其内所存在的方法. 微软官网给出的解释: 提供一个线程池,该线程池可用于执行任务.发送工作项.处理异步 ...

  4. .net 线程基础 ThreadPool 线程池

    1. ThreadPool 线程池异步: //public static bool QueueUserWorkItem(WaitCallback callBack); //public static ...

  5. 浅谈ThreadPool 线程池(引用)

    出自:http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html 浅谈ThreadPool 线程池 相关概念: 线程池可以看做容纳线程的 ...

  6. 多线程之旅(ThreadPool 线程池)

    一.什么是ThreadPool 线程池(源码) 1.线程池顾名思义,有我们的系统创建一个容器装载着我们的线程,由CLR控制的所有AppDomain共享.线程池可用于执行任务.发送工作项.处理异步 I/ ...

  7. 多线程 ThreadPool线程池

    简单说明一下: 线程池可以看做容纳线程的容器:一个应用程序最多只能有一个线程池:ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池: 每排入一个工作函数,就相 ...

  8. Delphi ThreadPool 线程池(Delphi2009以上版本适用)

    http://blog.sina.com.cn/s/blog_6250a9df0101kref.html 在网上查找Delphi线程池,结果发现寥寥无几. 看了半天源代码,弄得一头雾水,觉得不容易理解 ...

  9. ThreadPool 线程池的作用

    相关概念: 线程池可以看做容纳线程的容器: 一个应用程序最多只能有一个线程池: ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池: 每排入一个工作函数,就相 ...

  10. 『Python』 ThreadPool 线程池模板

    Python 的 简单多线程实现 用 dummy 模块 一句话就可以搞定,但需要对线程,队列做进一步的操作,最好自己写个线程池类来实现. Code: # coding:utf-8 # version: ...

随机推荐

  1. Android应用程序框架层和系统运行库层日志系统源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6598703 在开发Android应用程序时,少 ...

  2. StaggeredGridView+universal-image-loader载入网路图片实现瀑布流

    StaggeredGridView 开源lib  https://github.com/maurycyw/StaggeredGridView 文章demo下载地址  http://download.c ...

  3. 从零开始学C++之STL(七):剩下5种算法代码分析与使用示例(remove 、rotate 、sort、lower_bound、accumulate)

    一.移除性算法 (remove)  C++ Code  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ...

  4. IoC容器Autofac之实例引入(一)

    先不必尝试理解IOC,先来看段代码. 一.一个没有使用IoC的例子 public class MPGMovieLister { public Movie[] GetMPG() { var finder ...

  5. Android 控件 -------- AutoCompleteTextView 动态匹配内容,例如 百度搜索提示下拉列表功能

    AutoCompleteTextView 支持基本的自动完成功能,适用在各种搜索功能中,并且可以根据自己的需求设置他的默认显示数据.两个控件都可以很灵活的预置匹配的那些数据,并且可以设置输入多少值时开 ...

  6. /调整button的title的位置

    [bottomButton setTitleEdgeInsets:UIEdgeInsetsMake(10, -190, 10, 44)];  //上左下右            ||button.co ...

  7. UITextView(文本视图) 学习之初体验

    UITextView文本视图相比与UITextField直观的区别就是UITextView可以输入多行文字并且可以滚动显示浏览全文.常见UITextView使用在APP的软件简介.内容详情显示.小说阅 ...

  8. C# 操作系统防火墙

    很多时候,我们的程序是通过网络通信(如TCP或者UDP协议+端口),而将制作好的程序安装包给客户用时,发现会出现不能通信的现象(或者在这台电脑是可以的,却在另一台不可以),原因是防火墙阻止了,需要添加 ...

  9. OpenCV——CvMatchShapes函数

    功能:根据计算比较两张图像Hu不变距(函数返回值代表相似度大小,完全相同的图像返回值是0,返回值最大是1) double cvMatchShapes(const void* object1, cons ...

  10. eclipse中默认的提示键

    Alt+/:代码提示 Ctrl+/:注释/取消注释 Ctrl+D:删除光标所在行 Ctrl+K:将光标停留在变量上,按Ctrl+K键可以查找到下一个同样的变量 Shift+Ctrl+K:和Ctrl+K ...