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

使用ThreadPool来访问线程池

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

使用Task来访问线程池

引入了Task之后,你可以用如下实现来替代ThreadPool

这些实现都是等价的。Task本身实现了很多ThreadPool不能做的事情。

使用Task来获得线程的返回值

使用Task来等待线程结束

更多Task同步编程的使用,请参见(还没写,先给自己挖个坑O(∩_∩)O)。

异步委托

ThreadPool.QueueUserWorkItem没有提供一种简单的机制来获取线程的返回值。异步委托解决了这个问题,支持了传入一系列的参数。此外,异步委托中没有处理的异常会很方便的在调用线程的重新抛出(在调用EndInvoke的时候),因此不需要显示的处理。

通过异步委托来执行任务主要分一下几步:

  1. 初始化并声明一个你想要执行的委托
  2. 在委托上调用BeginInvoke,把返回值保存为IAsyncResult中

调用BeginInvoke不会阻塞当前线程,因此你可以在调用完之后执行其他你想要同步的操作

  1. 当你需要获取委托的返回值时,调用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中的多线程 (二 线程池)的更多相关文章

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

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

  2. (原创)JAVA多线程二线程池

    一,线程池的介绍 线程池包括一下三种: 线程池名称 创建方法 特点 其他 固定大小线程池 ExecutorService threadpool = Executors.newFixedThreadPo ...

  3. 细说.NET 中的多线程 (一 概念)

    为什么使用多线程 使用户界面能够随时相应用户输入 当某个应用程序在进行大量运算时候,为了保证应用程序能够随时相应客户的输入,这个时候我们往往需要让大量运算和相应用户输入这两个行为在不同的线程中进行. ...

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

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

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

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

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

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

  7. 【温故而知新-万花筒】C# 异步编程 逆变 协变 委托 事件 事件参数 迭代 线程、多线程、线程池、后台线程

    额基本脱离了2.0 3.5的时代了.在.net 4.0+ 时代.一切都是辣么简单! 参考文档: http://www.cnblogs.com/linzheng/archive/2012/04/11/2 ...

  8. Java 基础 多线程和线程池基础

    一,多线程 1.1 多线程介绍 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线程:线程是进程中的一个执行单元,负 ...

  9. Java基础学习笔记: 多线程,线程池,同步锁(Lock,synchronized )(Thread类,ExecutorService ,Future类)(卖火车票案例)

    多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念.进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线 ...

随机推荐

  1. HighCharts中Y轴颜色设置

    yAxis: [{ title: { text: '', style: { color: '#2EBBD9' } }, labels: { formatter: function () { retur ...

  2. 跟我学-Java底层技术系列文章

    对于工作中经常用到的东西,还是多看看实现原理,这样用着才能放心. 源码思想学习计划: 1.java基础库  HashCode深入理解 java线程框架窥探 2.集合类     java枚举类使用 递归 ...

  3. flex中通过代码获取supermap的token

    最近工作中需要使用代码来获取supermap服务启动安全访问限制以后的token值,经过一番尝试,最终成功获取到,记录下里,以供翻阅 //get token public function getTo ...

  4. MySQL提示符含义

    http://www.splaybow.com/post/mysql-prompt-introduce.html mysql> 准备好接受新命令. 说明:正常等待输入的提示符. -> 等待 ...

  5. 简单跳转到微信分享,基于libWeiChatSDK 和简单的自定义UIActivityViewController

    一.自定义UIActivity: 如果想要自定义UIActivity必须知道UIActivityViewController.首先这个类主要是用于接受字符串,RUL类型和图片类型的数据用于分享和操作的 ...

  6. python第一天基础1-2

    python入门 1 第一个python代码: 在linux上创建第一个.py脚本 #!/usr/bin/env python #-*- coding:utf-8 -*- print "He ...

  7. 使用.NET读取exchange邮件

    公司有个第3方的系统,不能操作源码修改错误捕获,但是错误会发一个邮件出来,里面包含了主要的信息.于是想从邮件下手,提取需要的数据 开始考虑使用的是exchange service,主要参考http:/ ...

  8. js-正则表达式的替换

    正则表达式替换使用的是replace()方法.Replace()方法是用一些字符途欢另一些字符 语法:stringObject.replace(regexp,replacement) regexp 必 ...

  9. mysql数据表操作&库操作

    首先登陆mysql:mysql -uroot -proot -P3306 -h127.0.0.1 查看所有的库:show databases; 进入一个库:use database; 显示所在的库:s ...

  10. js获取div相对屏幕的坐标位置

    1:div相对屏幕的坐标位置 function getDivPosition(div){ var x = div.getBoundingClientRect().left; var y = div.g ...