C# 线程池异步调用
许多应用程序使用多个线程,但这些线程经常在休眠状态中耗费大量的时间来等待事件发生。其他线程可能进入休眠状态,并且仅定期被唤醒以轮询更改或更新状态信息,然后再次进入休眠状态。为了简化对这些线程的管理,.NET框架为每一个进程提供了一个线程池,使应用程序能够根据需要来有效地利用多个线程。一个线程监视排到线程池的若干个等待操作的状态。当一个等待操作完成时,线程池中的一个辅助线程就会执行对应的回调函数。线程池中的线程由系统进行管理,程序员不需要费力于线程管理,可以集中精力处理应用程序任务。
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间之后创建另一个辅助线程。但线程的数目永远不会超过最大值。超过最大值的其他线程可以排队,但它们要等到其他线程完成后才启动。
线程池特别适合于执行一些需要多个线程的任务。使用线程池能够优化这些任务的执行过程,从而提高吞吐量,它不仅能够使系统针对此进程优化该执行过程,而且还能够使系统针对计算机上的其他进程优化该执行过程。如果需要启动多个不同的任务,而不想分别设置每个线程的属性,则可以使用线程池。
如果应用程序需要对线程进行特定的控制,则不适合使用线程池,需要创建并管理自己的线程。不适合使用线程池的情形包括:
— 如果需要使一个任务具有特定的优先级。
— 如果具有可能会长时间运行(并因此阻塞其他任务)的任务。
— 如果需要将线程放置到单线程单元中(线程池中的线程均处于多线程单元中)。
— 如果需要用永久标识来标识和控制线程,比如想使用专用线程来中止该线程,将其挂起或按名称发现它。
System.Threading.ThreadPool类实现了线程池。ThreadPool类是一个静态类,它提供了管理线程池的一系列方法。
ThreadPool.QueueUserWorkItem方法在线程池中创建一个线程池线程来执行指定的方法(用委托WaitCallback来表示),并将该线程排入线程池的队列等待执行。QueueUserWorkItem方法的原型为:
public static Boolean QueueUserWorkItem(WaitCallback wc, Object state);
public static Boolean QueueUserWorkItem(WaitCallback wc);
这些方法将“工作项”(和可选状态数据)排列到线程池的线程中,并立即返回。工作项只是一种方法(由wc参数标识),它被调用并传递给单个参数,即状态(状态数据)。没有状态参数的QueueUserWorkItem版本将null传递给回调方法。线程池中的某些线程将调用System.Threading.WaitCallback委托表示的回调方法来处理该工作项。回调方法必须与System.Threading.WaitCallback委托类型相匹配。WaitCallback定义如下:
public delegate void WaitCallback(Object state);
调用QueueUserWorkItem时传入的Object类型参数将传递到任务过程,可以通过这种方式来向任务过程传递参数。如果任务过程需要多个参数,可以定义包含这些数据的类,并将类的实例强制转换为Object数据类型。
每个进程都有且只有一个线程池。当进程启动时,线程池并不会自动创建。当第一次将回调方法排入队列(比如调用ThreadPool.QueueUserWorkItem方法)时才会创建线程池。一个线程监视所有已排队到线程池中的任务。当某项任务完成后,线程池中的线程将执行相应的回调方法。在对一个工作项进行排队之后将无法取消它。
线程池中的线程数目仅受可用内存的限制。但是,线程池将对允许在进程中同时处于活动状态的线程数目强制实施限制(这取决于CPU的数目和其他因素)。默认情况下,每个系统处理器最多可以运行25个线程池线程。通过使用ThreadPool.GetMaxThreads和ThreadPool.SetMax
Threads方法,可以获取和设置线程池的最大线程数。
即使是在所有线程都处于空闲状态时,线程池也会维持最小的可用线程数,以便队列任务可以立即启动。将终止超过此最小数目的空闲线程,以节省系统资源。默认情况下,每个处理器维持一个空闲线程。使用ThreadPool.GetMinThreads和ThreadPool.SetMinThreads方法可以获取和设置线程池所维持的空闲线程数。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; namespace ThreadPoolApp
{
class Program
{
static void Main(string[] args)
{
int maxThreadNum, portThreadNum, minThreadNum;
Console.WriteLine("Main thread start:");
ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);
ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);
Console.WriteLine("The max thread num is {0}", maxThreadNum);
Console.WriteLine("The mix thread num is {0}", minThreadNum); for(int i=1; i<=8; i++)
{
ThreadPool.QueueUserWorkItem(Getvalue, i);
//Thread.Sleep(2000);
//ThreadPool.QueueUserWorkItem(Setvalue, i);
}
Console.WriteLine("Main thread: Doing other work here...");
Thread.Sleep(2000); ThreadPool.QueueUserWorkItem(Setvalue, 99999); Console.WriteLine("Hit <Enter> Key to end this program.");
Console.ReadLine();
}
private static void Getvalue(object sta)
{
Console.WriteLine("This is the {0} time to use this method.", sta);
Thread.Sleep(1000);
}
private static void Setvalue(object sta)
{
Console.WriteLine("Hello Hello {0}.", sta);
Thread.Sleep(1000);
}
}
}
//运行结果
Main thread start:
The max thread num is 500
The mix thread num is 2
Main thread: Doing other work here...
This is the 1 time to use this method.
This is the 2 time to use this method.
This is the 3 time to use this method.
This is the 4 time to use this method.
This is the 5 time to use this method.
This is the 6 time to use this method.
Hit <Enter> Key to end this program.
This is the 7 time to use this method.
This is the 8 time to use this method.
Hello Hello 99999.
C# 线程池异步调用的更多相关文章
- BeginInvoke 方法真的是新开一个线程进行异步调用吗?
转自原文BeginInvoke 方法真的是新开一个线程进行异步调用吗? BeginInvoke 方法真的是新开一个线程进行异步调用吗? 参考以下代码: public delegate void tre ...
- java future模式 所线程实现异步调用(转载
java future模式 所线程实现异步调用(转载) 在多线程交互的中2,经常有一个线程需要得到另个一线程的计算结果,我们常用的是Future异步模式来加以解决.Future顾名思意,有点像期货市场 ...
- 线程池 异步I/O线程 <第三篇>
在学习异步之前先来说说异步的好处,例如对于不需要CPU参数的输入输出操作,可以将实际的处理步骤分为以下三步: 启动处理: 实际的处理,此时不需要CPU参数: 任务完成后的处理: 以上步骤如果仅仅使用一 ...
- Android AsyncTask内部线程池异步执行任务机制简要分析
如下分析针对的API 25的AsyncTask的源码: 使用AsyncTask如果是调用execute方法则是同步执行任务,想要异步执行任务可以直接调用executeOnExecutor方法,多数情况 ...
- 转载 线程池 异步I/O线程 <第三篇>
在学习异步之前先来说说异步的好处,例如对于不需要CPU参数的输入输出操作,可以将实际的处理步骤分为以下三步: 启动处理: 实际的处理,此时不需要CPU参数: 任务完成后的处理: 以上步骤如果仅仅使用一 ...
- 高并发场景-请求合并(二)揭秘HystrixCollapser-利用Queue和线程池异步实现
背景 在互联网的高并发场景下,请求会非常多,但是数据库连接池比较少,或者说需要减少CPU压力,减少处理逻辑的,需要把单个查询,用某些手段,改为批量查询多个后返回. 如:支付宝中,查询"个人信 ...
- ThreadPool.QueueUserWorkItem引发的血案,线程池异步非正确姿势导致程序闪退的问题
ThreadPool是.net System.Threading命名空间下的线程池对象.使用QueueUserWorkItem实现对异步委托的先进先出有序的回调.如果在回调的方法里面发生异常则应用程序 ...
- Java ExecutorServic线程池(异步)
相信大家都在项目中遇到过这样的情况,前台需要快速的显示,后台还需要做一个很大的逻辑.比如:前台点击数据导入按钮,按钮后的服务端执行逻辑A,和逻辑B(执行大量的表数据之间的copy功能),而这时前台不能 ...
- java 线程池——异步任务
一.简单粗暴的线程 最原始的方式,当我们要并行的或者异步的执行一个任务的时候,我们会直接使用启动一个线程的方式,如下面所示: new Thread(new Runnable() { @Override ...
随机推荐
- synchronized常见用法解析及示例
synchronized作用:保证代码执行的原子性:保证可见性(与volatile作用相同) JAVA中synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法 ...
- Hibernate 配置详解(8)
hibernate.generate_statistics 这个配置大家应该都很熟悉,用于开启Hibernate统计信息,便于对Hibernate相关性能调试提供数据依据.在开发过程当中,可以把这个选 ...
- 【转】Compile、Make和Build的区别
原文网址:http://lavasoft.blog.51cto.com/62575/436216 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任 ...
- ARM架构和X86架构对比
转载地址 我们就ARM架构的系统与X86架构系统的特性进行一个系统分析,方便用户在选择系统时进行理性.合理的比价分析. 一.性能: X86结构的电脑无论如何都比ARM结构的系统在性能方面要快得多.强得 ...
- struct内存对齐
内存对齐其实是为了在程序运行的时候更快的查找内存而做的一种编译器优化. 我们先看这样一个例子: #include <iostream> using namespace std; struc ...
- 求解答,Android源码编译时怎样添加第三方jar包
各位大神好,遇到的问题如标题. 我用Eclipse写了一个android工程,但是这个工程需要到SDK的隐藏类,所有想在源码下编译,但是每次mm之后,都会出现错误,提示是找不到对应的类. 我需要加入的 ...
- Linux 多线程开发
在任何一个时间点上,线程是可结合的(joinable)或者是分离的(detached).一个可结合的线程能够被其他线程收回其资源和杀死.在被其他线程回收之前,它的存储器资源(例如栈)是不释放的.相反, ...
- 手动调整导航控制器中的viewcontroller
NSMutableArray *array = [[NSMutableArray alloc]initWithArray: [self.navigationController viewControl ...
- Vue.js快速入门
Vue.js介绍 Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的API,使得我们 ...
- 登录DSCCC控制台报错提示:安装错误代码: 3
登录DSCCC控制台报错内容:读取安装配置时出错 检查目录服务控制中心状态时出现意外错误. 显示详细资料 隐藏详细资料 安装错误代码: 3 堆栈: com.sun.directory.common.s ...