细说.NET中的多线程 (二 线程池)
上一章我们了解到,由于线程的创建,销毁都是需要耗费大量资源和时间的,开发者应该非常节约的使用线程资源。最好的办法是使用线程池,线程池能够避免当前进行中大量的线程导致操作系统不停的进行线程切换,当线程数量到达了我们设置的上限,线程会自动排队等待,当线程资源可用时,队列中的线程任务会依次执行,如果没有排队等候的资源,线程会变为闲置状态。
使用ThreadPool来访问线程池

这种做法可以让我们不用那么复杂的去实现创建,重用线程的逻辑,但是也有一些限制,比如由他内置的方法,我们不知道什么时候线程池里面的任务会结束,也不能获取线程的返回值。为了解决这些问题,微软引入了一个新的概念。
使用Task来访问线程池
引入了Task之后,你可以用如下实现来替代ThreadPool

这些实现都是等价的。Task本身实现了很多ThreadPool不能做的事情。
使用Task来获得线程的返回值

使用Task来等待线程结束

更多Task同步编程的使用,请参见(还没写,先给自己挖个坑O(∩_∩)O)。
异步委托
ThreadPool.QueueUserWorkItem没有提供一种简单的机制来获取线程的返回值。异步委托解决了这个问题,支持了传入一系列的参数。此外,异步委托中没有处理的异常会很方便的在调用线程的重新抛出(在调用EndInvoke的时候),因此不需要显示的处理。
通过异步委托来执行任务主要分一下几步:
- 初始化并声明一个你想要执行的委托
- 在委托上调用BeginInvoke,把返回值保存为IAsyncResult中
调用BeginInvoke不会阻塞当前线程,因此你可以在调用完之后执行其他你想要同步的操作
- 当你需要获取委托的返回值时,调用EndInvoke方法,把IAsyncResult传入EndInvoke中
阻塞的方式执行异步委托

EndInvoke主要做3件事: 1. 等待异步委托完成 2. 接收返回值 3. 把异步线程中未处理的异常在当前线程中重新抛出。
非阻塞的方式执行异步委托
你也可以在调用BeginInvoke的时候指定一个回调方法,这个方法会在异步委托结束的时候自动调用。这样异步委托就像是一个后台线程一样自动执行,不需要主线程等待。只需要在BeginInvoke的时候做一些额外的操作即可实现这种操作。

关于线程池
Jeffery在C# via CLR Chapter27中针对线程池的使用给出了一些建议。目前我们允许开发者来指定一个线程池的最大线程数。但是事实证明,我们往往不应该为一个线程池指定线程的上限,否则可能会出现程序死锁或者饿死的状态。比如你可能设置了1000个线程,但是某一时刻正好有第1001个线程需要等待所有线程结束才能执行,这种情况如果你限制了线程池线程的个数,就会出现死锁。从开发的另一个角度说,你也不应该限制一个进程使用多少资源,比如一个进程可以使用多少内存,使用多少带宽.因此虽然目前你可以通过GetMaxThreads, SetMaxThreads,GetMinThreads,SetMinThreads ,GetAvailableThreads来进行线程个数的限制,但是他仍然不建议大家这样做。这些限制可能会让你的程序运行的更慢。
关于使用Task访问线程池:
细说.NET中的多线程 (三 使用Task)
作者:独上高楼
出处:http://www.cnblogs.com/myprogram/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
细说.NET中的多线程 (二 线程池)的更多相关文章
- Qt中的多线程与线程池浅析+实例
1. Qt中的多线程与线程池 今天学习了Qt中的多线程和线程池,特写这篇博客来记录一下 2. 多线程 2.1 线程类 QThread Qt 中提供了一个线程类,通过这个类就可以创建子线程了,Qt 中一 ...
- (原创)JAVA多线程二线程池
一,线程池的介绍 线程池包括一下三种: 线程池名称 创建方法 特点 其他 固定大小线程池 ExecutorService threadpool = Executors.newFixedThreadPo ...
- 细说.NET 中的多线程 (一 概念)
为什么使用多线程 使用户界面能够随时相应用户输入 当某个应用程序在进行大量运算时候,为了保证应用程序能够随时相应客户的输入,这个时候我们往往需要让大量运算和相应用户输入这两个行为在不同的线程中进行. ...
- Python多线程、线程池及实际运用
我们在写python爬虫的过程中,对于大量数据的抓取总是希望能获得更高的速度和效率,但由于网络请求的延迟.IO的限制,单线程的运行总是不能让人满意.因此有了多线程.异步协程等技术. 下面介绍一下pyt ...
- 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法
[源码下载] 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法 作者:webabcd 介绍重新想象 Wi ...
- C#多线程之线程池篇1
在C#多线程之线程池篇中,我们将学习多线程访问共享资源的一些通用的技术,我们将学习到以下知识点: 在线程池中调用委托 在线程池中执行异步操作 线程池和并行度 实现取消选项 使用等待句柄和超时 使用计时 ...
- 【温故而知新-万花筒】C# 异步编程 逆变 协变 委托 事件 事件参数 迭代 线程、多线程、线程池、后台线程
额基本脱离了2.0 3.5的时代了.在.net 4.0+ 时代.一切都是辣么简单! 参考文档: http://www.cnblogs.com/linzheng/archive/2012/04/11/2 ...
- Java 基础 多线程和线程池基础
一,多线程 1.1 多线程介绍 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线程:线程是进程中的一个执行单元,负 ...
- Java基础学习笔记: 多线程,线程池,同步锁(Lock,synchronized )(Thread类,ExecutorService ,Future类)(卖火车票案例)
多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念.进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线 ...
随机推荐
- heap c++ 操作 大顶堆、小顶堆
在C++中,虽然堆不像 vector, set 之类的有已经实现的数据结构,但是在 algorithm.h 中实现了一些相关的模板函数.下面是一些示例应用 http://www.cplusplus.c ...
- jsp实现回车登录
<body onkeydown="if(event.keyCode==13){login()}"> 内容0...... </body> 注:body里面加上 ...
- Struts2注解使用说明
Struts2注解 1 Struts2注解的作用 使用注解可以用来替换struts.xml配置文件!!! 2 导包 必须导入struts2-convention-plugin-2.3.15.jar包, ...
- Fire
Fire 分析: 首先,明确题意:b1,b2,--,bn 交换为b2,--,bn,b1,但这并不是意味着只能从b1开始交换,(这点从样例中可以看出),并且也不意味着交换的必须是连续的一串,可以是几个单 ...
- vs2010的“应用程序向导”新建MFC程序报错“当前页面的脚本发送错误”
原创文章,欢迎阅读,禁止转载. 问题现象不知道从什么时候开始,我的vs2010不能新建MFC程序了,报错如图:... 解决方法根据提示排查,发现是应用程序向导的相关html被损坏了.从同事电脑上把 ...
- mysql无法登录
很久没用root账户登录mysql发现无法登录 以为root密码被修改 修改root密码后还是无法登录 判断ip没权限 运行 Grant all privileges on *.* to 'root' ...
- SpringMVC常用注解實例詳解3:@ResponseBody
我的開發環境框架: springmvc+spring+freemarker開發工具: springsource-tool-suite-2.9.0JDK版本: 1.6.0_29tomcat ...
- 如何解决WebService参数传递中文乱码问题
1,问题由来 我的主要工作是负责统一适配平台这块,主要任务是提供给客户统一的调用接口,客户使用这个接口可以通过我们再调不同厂家的接口.主要流程如下: 现在客户那边传来的请求报文里面包含中文,使用web ...
- oracle中用户删除不了,ORA-01940提示 “无法删除当前已连接用户”
Oracle删除用户的提示无法删除当前已连接用户两种解决方法如下: 1.先锁定用户.然后查询进程号,最后删除对应的进程.在删除对应的用户 SQL>alter user XXX account l ...
- .net之微信企业号开发(二) 企业号人员身份认证与开发
前言 这里完全可以链接一个登录页面,让用户输入用户名密码进行登录的...2333 但是,这样所就完全失去了微信企业号的意义,本来进入微信企业号的时候,就已经对人员身份进行认证了,你这里再让别人登录,不 ...