C#的线程池使用起来还是非常简单的,这里记录一下。

根据http://blog.csdn.net/chen_zw/article/details/7939834里的描述这里记录一下C#线程池的特点

  • 一个进程有且只能管理一个线程池。
  • 线程池线程都是后台线程(即不会阻止进程的停止)
  • 每个线程都使用默认堆栈大小,以默认的优先级运行,并处于多线程单元中。超过最大值的其他线程需要排队,但它们要等到其他线程完成后才启动。
  • 在CLR 2.0 SP1之前的版本中,线程池中 默认最大的线程数量 = 处理器数 * 25, CLR 2.0 SP1之后就变成了 默认最大线程数量 = 处理器数 * 250,线程上限可以改变,通过使用ThreadPool.GetMax+Threads和ThreadPool.SetMaxThreads方法,可以获取和设置线程池的最大线程数。
  • 默认情况下,每个处理器维持一个空闲线程,即默认最小线程数 = 处理器数。
  • 当进程启动时,线程池并不会自动创建。当第一次将回调方法排入队列(比如调用ThreadPool.QueueUserWorkItem方法)时才会创建线程池。
  • 在对一个工作项进行排队之后将无法取消它。
  • 线程池中线程在完成任务后并不会自动销毁,它会以挂起的状态返回线程池,如果应用程序再次向线程池发出请求,那么这个挂起的线程将激活并执行任务,而不会创建新线程,这将节约了很多开销。只有线程达到最大线程数量,系统才会以一定的算法销毁回收线程。

在使用线程池的时候,需要初始化其状态

ManualResetEvent eventX = new ManualResetEvent(false);//表示线程池的状态 false代表非终结状态

根据https://www.cnblogs.com/tianboblog/p/5393444.html介绍:

当初始化为true时,为终止状态

static ManualResetEvent _mre = new ManualResetEvent(true);

当初始化为false时,为非终止状态

static ManualResetEvent _mre = new ManualResetEvent(false);
 

终止状态时WaitOne()允许线程访问下边的语句

非终止状态时WaitOne()阻塞线程,不允许线程访问下边的语句

把非终止状态改为终止状态用Set()方法

把终止状态改为非终止状态用Reset()方法

//按钮事件

private void btnBatchSend_Click(object sender, RoutedEventArgs e)
{

eventX.Reset();
ThreadPool.SetMinThreads(1, 1);//设置线程池在新请求预测中维护的空闲线程数
ThreadPool.SetMaxThreads(10,10);//设置可以同时处于活动状态的线程池的最大请求数目

以上两句必须都有才行

//循环设置执行对象,

for (int i = 0; i < list.Count; i++)
{

ThreadPool.QueueUserWorkItem(tranSend, oj);//

}

eventX.WaitOne();//当是非终结状态时,会阻塞主线程
eventX.Reset();//设置为非终结状态

}

worker.RunWorkerCompleted += (o, ea) =>
{
//sb.Append("主线程执行完毕");
//this.txt_cansole.Text = sb.ToString();
this.btnBatchCheck.IsEnabled = true;
this.btnBatchSend.Visibility = Visibility.Visible;
this.btnStopSend.Visibility = Visibility.Collapsed;
};
this.btnBatchCheck.IsEnabled = false;
this.btnBatchSend.Visibility = Visibility.Collapsed;
this.btnStopSend.Visibility = Visibility.Visible;
worker.RunWorkerAsync();

//每个线程将会执行的任务

private void tranSend(object order)
{

Order s = order as Order;

//当是最后一个order 或者 用户点了停止按钮时
if (s.IsLas || Break)
{
eventX.Set();//当点了停止按钮时,将线程池信号灯状态设置为终结状态这时会通知主线程继续往下执行
return;
}

//真正的执行任务代码
s.SendMessage = ">>";
s.ItemStatus = 1; /

}

可以看出来熟练C#线程池的使用主要是控制好信号灯的状态,当主线程往下执行时,for循环里的代码会很快执行完毕,虽然最多只允许了十个线程同时活动,但十个之后的对象已经加入了队列,需要中断时,需要在执行任务里去自行判断。

if (s.IsLas || Break)
{
eventX.Set();//当点了停止按钮时,将线程池信号灯状态设置为终结状态这时会通知主线程继续往下执行
return;
}

C# 线程池的使用 终止线程池中的队列的更多相关文章

  1. Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  2. Java实现终止线程池中正在运行的定时任务

    源于开发 最近项目中遇到了一个新的需求,就是实现一个可以动态添加定时任务的功能.说到这里,有人可能会说简单啊,使用quartz就好了,简单粗暴.然而quartz框架太重了,小项目根本不好操作啊.当然, ...

  3. 一个神奇的bug:OOM?优雅终止线程?系统内存占用较高?

    摘要:该项目是DAYU平台的数据开发(DLF),数据开发中一个重要的功能就是ETL(数据清洗).ETL由源端到目的端,中间的业务逻辑一般由用户自己编写的SQL模板实现,velocity是其中涉及的一种 ...

  4. java线程中断和终止线程运行

    ava中启动一个线程很容易,通常情况下我们都是等到任务运行结束后让线程自行停止.但有时需要在任务正在运行时取消他们,使得线程快速结束.对此Java并没有提供任何机制.但是我们可以通过Java提供的线程 ...

  5. 《Java并发编程》之线程中断与终止线程运行

    Java中启动一个线程很容易,通常情况下我们都是等到任务运行结束后让线程自行停止.但有时需要在任务正在运行时取消他们,使得线程快速结束.对此Java并没有提供任何机制.但是我们可以通过Java提供的线 ...

  6. Java终止线程的三种方式

    停止一个线程通常意味着在线程处理任务完成之前停掉正在做的操作,也就是放弃当前的操作. 在 Java 中有以下 3 种方法可以终止正在运行的线程: 使用退出标志,使线程正常退出,也就是当 run() 方 ...

  7. Java多线程并发01——线程的创建与终止,你会几种方式

    本文开始将开始介绍 Java 多线程与并发相关的知识,多谢各位一直以来的关注与支持.关注我的公众号「Java面典」了解更多 Java 相关知识点. 线程的创建方式 在 Java 中,用户常用的主动创建 ...

  8. Android线程管理之ThreadPoolExecutor自定义线程池

    前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...

  9. java多线程系类:JUC线程池:03之线程池原理(二)(转)

    概要 在前面一章"Java多线程系列--"JUC线程池"02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包 ...

随机推荐

  1. C++中的异常处理(下)

    1,catch 语句块中可以抛出异常: 1,示意图: 2,func() 在 try 语句块中,说明它有可能抛出异常,抛出的异常有可能是整型或其它类型: 3,catch 语句块处理方式是将异常重新抛出去 ...

  2. Liunx平台安装MySQL操作步骤

    使用yum安装MySQL 第一步 第二步 第三步 数据库安装成功 修改数据库密码,并且删除匿名用户.禁止root远程登录.删除test数据库.刷新权限. 使用命令进入后,找到自己的临时密码,并且修改 ...

  3. 不要62(数位dp)

    题目传送门 不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. python 字典(dictionary)一些方法

    1.python 字典(Dictionary) keys() 函数以列表返回一个字典所有的键. keys()语法: dict.keys() 2.setdefault()方法 python字典setde ...

  5. cmd中java的编译命令——java和javac、javap

    最近重新复习了一下java基础,这里便讲讲对于一个类文件如何编译.运行.反编译的.也让自己加深一下印象   如题,首先我们在桌面,开始->运行->键入cmd 回车,进入windows命令行 ...

  6. 【学习总结】Python-3-身份运算符 is 与 == 区别

    参考:菜鸟教程-Python3运算符 身份运算符 is 和 is not:用于比较两个对象的存储单元 判断两个标识符是不是引用自相同或不同对象,返回一个布尔值 对于"同一个对象"中 ...

  7. split slice splice的简单区别

    split slice splice的简单区别 split: 分割 //字符串方法 string.split let str = 'hello world'; //str.split('') 以什么东 ...

  8. Netflix:我们为什么要将GraphQL引入前端架构?

    作者|Artem Shtatnov译者|无明 在这篇文章中,我们将分享 Netflix 在这些应用程序的前端架构中引入 GraphQL 所积累的经验. 在内部,我们把用于管理广告创建和组装的主要应用程 ...

  9. python-django_rest_framework中的request/Response

    rest_framework中的request是被rest_framework再次封装过的,并在原request上添加了许多别的属性: (原Django中的request可用request._requ ...

  10. GitHub 创建工程

    创建本地代码仓库 打开Git Bash 首先配置自己的身份,这样在提交代码的时候就能知道是谁提交的 输入git config --global user.name 名字 git config --gl ...