C#线程池
来源:互联网 发布:微小企业会计软件好吗? 编辑:程序博客网 时间:2024/05/01 13:37
打算写一篇线程池的文章,看到csdn上一哥们已经写的很好了,果断转了
原文地址 : http://blog.csdn.net/chen_zw/article/details/7939834
一、ThreadPool类
- GetMaxThreads() // 获取可以同时处于活动状态的线程池请求的最大数目。所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。
- 函数原型:public static void GetMaxThreads (out int workerThreads,out int completionPortThreads)
参数2:completionPortThreads :线程池中异步 I/O 线程的最大数目。 - 函数原型:public static void GetMaxThreads (out int workerThreads,out int completionPortThreads)
- GetMinThreads() // 获取线程池维护的空闲线程数。
- 函数原型:public static void GetMinThreads (out int workerThreads,out int completionPortThreads)
参数1:workerThreads:当前由线程池维护的空闲辅助线程的最小数目。
参数2:completionPortThreads:当前由线程池维护的空闲异步 I/O 线程的最小数目。
- 函数原型:public static void GetMinThreads (out int workerThreads,out int completionPortThreads)
- GetAvailableThreads() // 获取由 GetMaxThreads 返回的线程池线程的最大数目和当前活动数目之间的差值。
- 函数原型:public static void GetAvailableThreads (out int workerThreads,out int completionPortThreads)
参数2:completionPortThreads:可用异步 I/O 线程的数目。
- QueueUserWorkItem() // 将方法排入队列以便执行。此方法在有线程池线程变得可用时执行。
- 重载方法1:public static bool QueueUserWorkItem (WaitCallback callBack)
- 重载方法2:public static bool QueueUserWorkItem (WaitCallback callBack,Object state)
返回值:如果将方法成功排入队列,则为 true;否则为 false。
备注:WaitCallback 回调方法必须与System.Threading.WaitCallback委托类型相匹配。WaitCallback函数原型:public delegate void WaitCallback(Object state);
调用QueueUserWorkItem可以通过Object来向任务过程传递参数。如果任务过程需要多个参数,可以定义包含这些数据的类,并将类的实例强制转换为Object数据类型。
- RegisterWaitForSingleObject() // 将指定的委托排队到线程池。当发生以下情况之一时,辅助线程将执行委托。1、指定对象处于终止状态。2、超时间隔已过期。
- 重载方法1:public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,WaitOrTimerCallback callBack,Object state,int millisecondsTimeOutInterval,bool executeOnlyOnce)
参数2:callBackwaitObject :参数终止时调用的 WaitOrTimerCallback 委托。
WaitOrTimerCallback委托原型:public delegate void WaitOrTimerCallback (Object state,bool timedOut)
参数3:state:传递给委托的对象。
参数4:millisecondsTimeOutInterval:以毫秒为单位的超时时间。如果 millisecondsTimeOutInterval 参数为零 (0),则函数测试
对象的状态并立即返回。如果 millisecondsTimeOutInterval 为 -1 或 Timeout.Infinite,则函数的超时间隔永远不过期。
参数5:executeOnlyOnce:如果为 true,表示在调用了委托后,线程将不再在 waitObject 参数上等待;如果为false,表示每次完成等待操作后都重置计时器,直到注销等待。(是否只调用一次)
返回值:封装本机句柄的 RegisteredWaitHandle- 重载方法2:public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,WaitOrTimerCallback callBack,Object state,long millisecondsTimeOutInterval,bool executeOnlyOnce) // 64位的超时时间
- 重载方法3:public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,WaitOrTimerCallback callBack,Object state,TimeSpan timeout,bool executeOnlyOnce)
参数4:timeout:TimeSpan 所表示的超时时间。如果 timeout 为零,则函数测试对象的状态并立即返回。如果 timeout 为 -1,则函数的超时间隔永远不过期。 - 重载方法4:public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,WaitOrTimerCallback callBack,Object state,uint millisecondsTimeOutInterval,bool executeOnlyOnce)
- 重载方法1:public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,WaitOrTimerCallback callBack,Object state,int millisecondsTimeOutInterval,bool executeOnlyOnce)
- UnsafeQueueUserWorkItem() // 非安全性注册一个等待 WaitHandle 的委托(将方法排入队列以便执行)。
- 函数原型:public static bool UnsafeQueueUserWorkItem (WaitCallback callBack,Object state) //不将调用堆栈传播到辅助线程上。这允许代码失去调用堆栈,从而提升了它的安全特权
- 函数原型:public static bool UnsafeQueueUserWorkItem (WaitCallback callBack,Object state) //不将调用堆栈传播到辅助线程上。这允许代码失去调用堆栈,从而提升了它的安全特权
- UnsafeRegisterWaitForSingleObject() // 非安全性将指定的委托排队到线程池。
- 重载方法1:public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject,WaitOrTimerCallback callBack,Object state,int
- 重载方法1:public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(WaitHandle waitObject,WaitOrTimerCallback callBack,Object state,int
- SetMaxThreads() // 设置可以同时处于活动状态的线程池的最大请求数目(不考虑计算机处理器的数目)
- 函数原型:public static bool SetMinThreads (int workerThreads,intcompletionPortThreads)
参数2:completionPortThreads::要由线程池维护的新的最小空闲异步 I/O 线程数。
返回值:如果更改成功,则为 true;否则为 false。
备注:如果指定一个负数或者一个大于最大活动线程池线程数的正数(使用 GetMaxThreads 获取),则 SetMinThreads 返回 false 并且不更改任何一个最小值。
将空闲线程数减少到小于处理器的数目会影响性能。而维护大量的空闲线程会消耗系统资源。您可能需要调整空闲线程数,以实现最佳的总体性能。对于那些在一段时间不活动之后爆发大量活动的应用,少量增加空闲线程数可以显著提高吞吐量。 - 函数原型:public static bool SetMinThreads (int workerThreads,intcompletionPortThreads)
- SetMinThreads() // 设置线程池在新请求预测中维护的空闲线程数(不考虑计算机处理器的数目)
- 函数原型:public static bool SetMinThreads (int workerThreads,intcompletionPortThreads)
参数2:completionPortThreads:要由线程池维护的新的最小空闲异步 I/O 线程数。
返回值:如果更改成功,则为 true;否则为 false。 - 函数原型:public static bool SetMinThreads (int workerThreads,intcompletionPortThreads)
二、线程池的几个重要特点:
- 一个进程有且只能管理一个线程池。
- 线程池线程都是后台线程(即不会阻止进程的停止)
- 每个线程都使用默认堆栈大小,以默认的优先级运行,并处于多线程单元中。超过最大值的其他线程需要排队,但它们要等到其他线程完成后才启动。
- 在CLR 2.0 SP1之前的版本中,线程池中 默认最大的线程数量 = 处理器数 * 25, CLR 2.0 SP1之后就变成了 默认最大线程数量 = 处理器数 * 250,线程上限可以改变,通过使用ThreadPool.GetMax+Threads和ThreadPool.SetMaxThreads方法,可以获取和设置线程池的最大线程数。
- 默认情况下,每个处理器维持一个空闲线程,即默认最小线程数 = 处理器数。
- 当进程启动时,线程池并不会自动创建。当第一次将回调方法排入队列(比如调用ThreadPool.QueueUserWorkItem方法)时才会创建线程池。
- 在对一个工作项进行排队之后将无法取消它。
- 线程池中线程在完成任务后并不会自动销毁,它会以挂起的状态返回线程池,如果应用程序再次向线程池发出请求,那么这个挂起的线程将激活并执行任务,而不会创建新线程,这将节约了很多开销。只有线程达到最大线程数量,系统才会以一定的算法销毁回收线程。
三、不适合使用线程池的情形包括:
- 如果需要使一个任务具有特定的优先级。
- 如果具有可能会长时间运行(并因此阻塞其他任务)的任务。
- 如果需要将线程放置到单线程单元中(线程池中的线程均处于多线程单元中)。
- 如果需要用永久标识来标识和控制线程,比如想使用专用线程来中止该线程,将其挂起或按名称发现它。
- 如果您需要运行与用户界面交互的后台线程,.NET Framework 2.0 版提供了 BackgroundWorker 组件,该组件可以使用事件与用户界面线程的跨线程封送进行通信。
四、线程池的优势:
- 可以避免创建和销毁消除的开支,从而可以实现更好的性能和系统稳定性。
- 把线程交给系统进行管理,程序员不需要费力于线程管理,可以集中精力处理应用程序任务。
示例:
- class Power //计算次方类
- {
- public double num = -1;
- public void TaskProc(object o) //计算次方方法,注意必须有个传入参数object,必须与public delegate void WaitCallback(Object state);委托类型一致
- {
- num = Math.Pow(Convert.ToDouble(o), 8);
- }
- }
- /// <summary>
- /// 多线程计算数次方
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Form1_Load(object sender, EventArgs e)
- {
- int maxThreadNum, portThreadNum;
- int minThreadNum;
- ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);
- ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);
- MessageBox.Show(maxThreadNum + "," + minThreadNum + "," + portThreadNum); //显示最大线程上限和最小空闲线程及异步 I/O 线程的最大数目
- Power p1 = new Power();
- ThreadPool.QueueUserWorkItem(new WaitCallback(p1.TaskProc),6); //开始计算6的8次方的任务
- Power p2 = new Power();
- ThreadPool.QueueUserWorkItem(new WaitCallback(p2.TaskProc),7); //开始计算7的8次方的任务
- while (p1.num == -1 || p2.num == -1); //知道2个线程都计算出结果
- MessageBox.Show(Convert.ToString(p1.num + p2.num)); //获取6^8 + 7^8的和
- }
六、线程池中线程同步:
具体说明请看上面ThreadPool类的RegisterWaitForSingleObject()方法。
- private void button5_Click(object sender, EventArgs e)
- {
- ManualResetEvent mre = new ManualResetEvent(false); //注册监听的handle,如果为 true,则将初始状态设置为终止;如果为 false,则将初始状态设置为非终止。
- //Mutex mtx = new Mutex(true); //如果给调用线程赋予互斥体的初始所属权,则为 true;否则为 false。
- //AutoResetEvent are = new AutoResetEvent(false); //如果为 true,则将初始状态设置为终止;如果为 false,则将初始状态设置为非终止。
- ThreadPool.RegisterWaitForSingleObject(mre, new WaitOrTimerCallback(PoolFunc), 34, Timeout.Infinite, true); //传递参数34,无限时间监听,只调用一次
- //ThreadPool.RegisterWaitForSingleObject(mtx, new WaitOrTimerCallback(PoolFunc), null, Timeout.Infinite, true);
- //ThreadPool.RegisterWaitForSingleObject(are, new WaitOrTimerCallback(PoolFunc), 34, Timeout.Infinite, true);
- mre.Set(); //将事件状态设置为终止状态,RegisterWaitForSingleObject开始调用执行PoolFunc方法
- //mtx.ReleaseMutex();
- //are.Set();
- }
- private void PoolFunc(object obj, bool TimedOut)
- {
- MessageBox.Show("Synchronization object signaled,object:"+obj+",Thread:" + Thread.CurrentThread.GetHashCode() + " Is pool: " + Thread.CurrentThread.IsThreadPoolThread);
- }
0 0
- C#线程与线程池
- .Net C# 线程池
- C# 线程池示例
- C# 线程池
- C#线程池实例
- c# 线程池
- C#线程池
- c#线程池详解
- c#线程池详解
- C#线程池
- C#线程池
- c#线程池详解
- C#线程池
- c#线程池详解
- C#线程池
- C#线程池用法
- C#线程池用法
- c# 线程池 多线程
- android OTA 升级优化之一: recovery支持分区更新
- MYSQL跨服务器操作数据库表
- 九度OJ--1113--二叉树
- 计算机文化基础》
- Spring+ ibatis批量插入数据
- C#线程池
- Morris二叉树遍历算法
- exchange 2010 数据结构
- android NDK的android.mk文件的详解
- Oracle一个中文汉字占用几个字节---小笔记
- C++专题:strlen和sizeof的区别
- Java + Flex + blazeds开发环境配置(Java工程和Flex工程独立)
- 2014~?学习计划
- uva 10269 最短路