线程池System.Threading.ThreadPool,可用于发送工作项、处理异步I/O、代表其它线程等待以及处理计时器。基本用法:

        public void Main()
{
ThreadPool.QueueUserWorkItem(JobForAThread); // 将某工作交给线程池 } void JobForAThread(object state) // 线程要执行的工作:满足 委托WaitCallback
{
for (int i = ; i <= ; i++)
{
Console.WriteLine("Running Thread {0},Step {1}", Thread.CurrentThread.ManagedThreadId, i);
Thread.Sleep();
}
}

在执行  ThreadPool.QueueUserWorkItem() 方法后,处理器就会自动在池中选择一个线程来处理“工作内容”。

1.如果线程池还没有运行,就会创建一个线程池,并启动第一个线程。

2.如果线程池已经在运行,且至少有一个空闲的线程,线程池就会把改“工作内容”交给这个空闲的线程来处理。

3.如果当时线程池没有空闲的线程,该工作就会处于等待状态,直到有空闲线程来处理它。

过 ThreadPool.GetMaxThreads() 方法来 检索可以同时处于活动状态的线程池请求的数目。

            int vWorkerThreads;
int vCompletionPortThreads;
ThreadPool.GetMaxThreads(out vWorkerThreads, out vCompletionPortThreads);
Console.WriteLine("池中辅助线程的最大数{0},池中异步 I/O 线程的最大数{1}", vWorkerThreads, vCompletionPortThreads);

可以通过 ThreadPool.SetMaxThreads() 方法设置可以同时处于活动状态的线程池请求的数目。

ThreadPool.SetMaxThreads(5, 4);

但是,不能将辅助线程的数目或异步I/O完成线程的数目设置位 小于 计算机处理器的数目。线程池使用很简单,但又一些限制:

1.线程池中的所有线程都是后台线程。如果进程的所有前台线程都结束了,所有后台线程就会停止。不能把入池的线程改为前台线程。

2.不能给入池的线程设置优先级或名称。

3.入池的线程只能用于时间较短的任务。如果线程要一直运行,就应该使用Thread类创建一个线程。

 JobForAThread() 工作任务传递参数 object state,调用:

        public void Main()
{
ThreadPool.QueueUserWorkItem(JobForAThread,"这是传递给工作内容的参数"); // 添加工作的同时,传递参数 Console.ReadKey(); // 让主线程等待,否则“一闪而过”
} void JobForAThread(object state)
{
Console.WriteLine("收到信息:{0}", (string)state); // 处理传进来的数据 for (int i = ; i <= ; i++)
{
Console.WriteLine("Running Thread {0},Step {1}", Thread.CurrentThread.ManagedThreadId, i);
Thread.Sleep();
}
}

简单的控制操作

般情况下,“工作”交给线程池后,就不受控制了, 它会由处理器自动决定什么时候开始执行(当然是有空闲线程才行)。可以通过以下代码,让工作在指定时候以后再开始执行。

        ManualResetEvent mManualEvent;

        public void Main()
{
mManualEvent = new ManualResetEvent(false); // 实例 ThreadPool.QueueUserWorkItem(JobForAThread); Console.WriteLine("{0} 任务已经交给线程池了,但是它没有执行.", DateTime.Now.ToString("HH:mm:ss"));
Thread.Sleep(); // 等待 10s
mManualEvent.Set(); // 发出信号,让线程继续执行 Console.ReadKey(); // 让主线程等待,否则“一闪而过”
} void JobForAThread(object state)
{
mManualEvent.WaitOne(); // 等待 “ mManualEvent.Set();” 这一句执行(发送信号)
Console.WriteLine("{0} 现在开始执行任务啦.", DateTime.Now.ToString("HH:mm:ss")); for (int i = ; i <= ; i++)
{
Console.WriteLine("Running Thread {0},Step {1}", Thread.CurrentThread.ManagedThreadId, i);
Thread.Sleep();
}
}

运行结果:

这里在将工作交给线程池后,线程执行工作时,一直阻塞在 mManualEvent.WaitOne(); 这一句,直到10s后主线程发出了信号,该工作才继续执行后续代码。这是一种“假开始”控制操作,本质上并没有实现让指定工作在希望的时候开始工作。这里 在初始化 ManualResetEvent 对象时参数 false 表示,默认将信号置为“阻塞状态”,通过代码  mManualEvent.Set(); 将信号置为“可继续状态”。反之,可以通过代码 mManualEvent.Reset(); 将线程置为“阻塞状态”。

时,需要等待所有线程池中的线程执行完成后,才继续执行其它某些代码。

        AutoResetEvent[] mAutoResetEvent;
public void Main()
{
mAutoResetEvent = new AutoResetEvent[]{
new AutoResetEvent(false), // 默认信号为 阻塞
new AutoResetEvent(false),
new AutoResetEvent(false)
}; for (int i = ; i < ; i++) // 创建3个工作
{
Thread.Sleep();
ThreadPool.QueueUserWorkItem(JobForAThread, i);
}
Console.WriteLine("所有工作已经添加到池中...");
WaitHandle.WaitAll(mAutoResetEvent); // 等待 mAutoResetEvent 中所有信号变为 继续 后,继续后面代码
Console.WriteLine("所有工作已经完成了"); Console.ReadKey(); // 让主线程等待,否则“一闪而过”
} void JobForAThread(object state)
{
int vJobIndex = (int)state;
Console.WriteLine("Job {0} Started.", vJobIndex);
for (int i = ; i <= ; i++)
{
Console.WriteLine("Running Thread {0},Step {1},Job {2} ", Thread.CurrentThread.ManagedThreadId, i, vJobIndex);
Thread.Sleep();
} mAutoResetEvent[vJobIndex].Set();
}

运行结果:

[http://www.cnblogs.com/CUIT-DX037/]

C# 多线程之线程池的更多相关文章

  1. C#多线程之线程池篇3

    在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识.在这一篇中,我们主要学习如何使用等待句柄和超时.使用计时器和使用BackgroundWorker组件的相关 ...

  2. C#多线程之线程池篇2

    在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我 ...

  3. C#多线程之线程池篇1

    在C#多线程之线程池篇中,我们将学习多线程访问共享资源的一些通用的技术,我们将学习到以下知识点: 在线程池中调用委托 在线程池中执行异步操作 线程池和并行度 实现取消选项 使用等待句柄和超时 使用计时 ...

  4. 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法

    [源码下载] 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法 作者:webabcd 介绍重新想象 Wi ...

  5. ExecutorService 建立一个多线程的线程池的步骤

    ExecutorService 建立一个多线程的线程池的步骤: 线程池的作用: 线程池功能是限制在系统中运行的线程数. 依据系统的环境情况,能够自己主动或手动设置线程数量.达到执行的最佳效果:少了浪费 ...

  6. C#多线程和线程池问题

    static void Main(string[] args) { Thread threadA = new Thread(ThreadMethod); //执行的必须是无返回值的方法 threadA ...

  7. Qt多线程-QThreadPool线程池与QRunnable

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt多线程-QThreadPool线程池与QRunnable     本文地址:https:/ ...

  8. Java基础教程:多线程基础——线程池

    Java基础教程:多线程基础——线程池 线程池 在正常负载的情况瞎,通过为每一个请求创建一个新的线程来提供服务,从而实现更高的响应性. new Thread(runnable).start() 在生产 ...

  9. Qt中的多线程与线程池浅析+实例

    1. Qt中的多线程与线程池 今天学习了Qt中的多线程和线程池,特写这篇博客来记录一下 2. 多线程 2.1 线程类 QThread Qt 中提供了一个线程类,通过这个类就可以创建子线程了,Qt 中一 ...

  10. Python多线程、线程池及实际运用

    我们在写python爬虫的过程中,对于大量数据的抓取总是希望能获得更高的速度和效率,但由于网络请求的延迟.IO的限制,单线程的运行总是不能让人满意.因此有了多线程.异步协程等技术. 下面介绍一下pyt ...

随机推荐

  1. tensorflow placeholder

    placeholder 是 Tensorflow 中的占位符,暂时储存变量. Tensorflow 如果想要从外部传入data, 那就需要用到 tf.placeholder(), 然后以这种形式传输数 ...

  2. 第六课 ROS的空间描述和变换

    1.空间描述与变换 有两个坐标系A和B,B坐标系中有一个点P,如何把B坐标系中的P映射到A坐标系呢,这就涉及到空间描述与变换, 先看一下旋转矩阵: 上面中间的行向量中的元素表示在B坐标系当中的元素用A ...

  3. 阶段2-新手上路\项目-移动物体监控系统\Sprint3-移动监控主系统设计与开发

    移动图像监控系统 去找一些相关开源程序进行移植:百度搜索-linux 移动监控 motion是一套免费开源的移动图像监测程序 前面我们已经使用了很多开源软件,他们的使用方法都是大同小异的 1).先在当 ...

  4. 25. CTF综合靶机渗透(17)

    靶机链接 https://www.vulnhub.com/entry/the-ether-evilscience,212 运行环境 本靶机提供了VMware的镜像,从Vulnhub下载之后解压,运行v ...

  5. sql server列转行的几种方法

    方法一,临时变量: declare @temp nvarchar(max)='' select @temp=coalesce(@temp,'')+Location+',' from( select d ...

  6. Swoole 整合成一个小框架

    目录 概述 效果 代码 小结 概述 这是关于 Swoole 学习的第六篇文章:Swoole 整合成一个小框架. 第五篇:Swoole 多协议 多端口 的应用 第四篇:Swoole HTTP 的应用 第 ...

  7. gulp使用文档

    gulp的优势 易于使用:通过代码优于配置的策略,Gulp让简单的任务简单,复杂的任务可管理. 构建快速:利用 Node.js 流的威力,你可以快速构建项目并减少频繁的 IO 操作. 插件高质:Gul ...

  8. hdu 1847 Good Luck in CET-4 Everybody!(巴什博弈)

    Good Luck in CET-4 Everybody! HDU - 1847 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Ci ...

  9. [Xcode 实际操作]四、常用控件-(14)使用UIWebView控件加载本地HTML

    目录:[Swift]Xcode实际操作 本文将演示使用网页视图,加载并渲染网页代码. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit im ...

  10. [Xcode 实际操作]四、常用控件-(10)动作表样式警告窗口的使用

    目录:[Swift]Xcode实际操作 本文将演示动作表单窗口的使用. 动作表单可以给用户展现一系列的选项, 和警告窗口不同的是,动作表单的展示形式和设备的尺寸有关. 在项目导航区,打开视图控制器的代 ...