NET 中的多线程
NET 中的多线程
为什么使用多线程
- 使用户界面能够随时相应用户输入
当某个应用程序在进行大量运算时候,为了保证应用程序能够随时相应客户的输入,这个时候我们往往需要让大量运算和相应用户输入这两个行为在不同的线程中进行。
- 效率原因
应用程序经常需要等待一些资源,如等待网络资源,等待io资源,等待用户输入等等。这种情况下使用多线程可以避免CPU长时间处于闲置状态。
用户态,内核态
线程内的资源有两种运行态,即用户态和内核态。某些运算可以在堆栈上进行,这种情况线程是在用户态运行的,某些需要高权限运行的指令,或者某些优先级很高的指令需要在操作系统内核中进行,这个时候线程会运行在内核态。出于安全原因,用户态和内核态的资源是不能够互相访问的,因此在用户态和内核态的切换过程中,我们需要进行相关上下文以及变量的复制,这意味的用户态和内核态的切换是以一定的时间消耗为代价的。
由于CPU是以时间片为单位进行线程的切换的,由于CPU的运算速度远大于内存的读写速度,因此CPU和内存之间通常有两级缓存,不同的线程的上下文访问的数据往往是不同的,这样线程的切换需要经常频繁的切换CPU缓存的内容,也需要更新线程的调度信息,这些都是需要花费一定的时间的,因此合理的使用多线程,来避免CPU不停的进行上下文切换。
System.Thread介绍
创建一个线程
创建每一个线程的时候,CLR都需要进行一系列的操作,如初始化线程的本地资源,为线程分配用户模式和内核模式下相应的堆栈,加载相应的托管,非托管资源等。
最简单常用的创建线程的方式是使用ThreadStart来创建线程,相关代码如下:

ThreadStart只需要一个委托即可,如果你善于使用匿名方法,也可以用匿名方法来代替委托,使用匿名方法的另一个好处是可以通过匿名方法的闭包特性来为新的线程传递参数。
虽然使用匿名方法的闭包特性可以很方便的为线程传递参数,但是也往往会带来一些不容易发现的问题,如下面的程序,由于i变量的共享,在运行的时候输出会有问题:

正确的写法应该是这样的:

线程异常的捕获
如果线程中可能需要捕获异常,那么我们不能这样做:

而是这样做:

System.Thread线程的成员
System.Threading.Thread帮助我们实现了一些线程的基本操作,如:
|
属性名称 |
说明 |
|
CurrentContext |
获取线程正在其中执行的当前上下文。 |
|
CurrentThread |
获取当前正在运行的线程。 |
|
ExecutionContext |
获取一个 ExecutionContext 对象,该对象包含有关当前线程的各种上下文的信息。 |
|
IsAlive |
获取一个值,该值指示当前线程的执行状态。 |
|
IsBackground |
获取或设置一个值,该值指示某个线程是否为后台线程。 |
|
IsThreadPoolThread |
获取一个值,该值指示线程是否属于托管线程池。 |
|
ManagedThreadId |
获取当前托管线程的唯一标识符。 |
|
Name |
获取或设置线程的名称。 |
|
Priority |
获取或设置一个值,该值指示线程的调度优先级。 |
|
ThreadState |
获取一个值,该值包含当前线程的状态。 |
|
方法名称 |
说明 |
|
Abort() |
终止本线程。 |
|
GetDomain() |
返回当前线程正在其中运行的当前域。 |
|
GetDomainId() |
返回当前线程正在其中运行的当前域Id。 |
|
Interrupt() |
中断处于 WaitSleepJoin 线程状态的线程。 |
|
Join() |
已重载。阻塞调用线程,直到某个线程终止时为止。 |
|
Resume() |
继续运行已挂起的线程。 |
|
Start() |
执行本线程。 |
|
Suspend() |
挂起当前线程,如果当前线程已属于挂起状态则此不起作用 |
|
Sleep() |
把正在运行的线程挂起一段时间。 |
前台线程vs后台线程
这里我们单独提一下前台线程和后台线程。在CLR中,线程分为前台线程和后台线程,当所有前台的线程执行完之后,CLR会强制结束所有正在运行的后台线程,并且不会出现任何异常。
因此你应该使用前台线程来做一些必须完成的任务,比如把流从内存中写到磁盘上。后台线程可以做一些不那么重要的事情。一旦线程对象的生命周期开始,你就不能修改IsBackground值。
由于线程是非常昂贵的资源,我们经常需要控制允许多少线程同时运行,如何控制线程的生命周期,如何管理线程,这里我们引入了线程池的概念。
细说.NET中的多线程 (二 线程池)
NET 中的多线程的更多相关文章
- 细说.NET 中的多线程 (一 概念)
为什么使用多线程 使用户界面能够随时相应用户输入 当某个应用程序在进行大量运算时候,为了保证应用程序能够随时相应客户的输入,这个时候我们往往需要让大量运算和相应用户输入这两个行为在不同的线程中进行. ...
- 细说.NET中的多线程 (二 线程池)
上一章我们了解到,由于线程的创建,销毁都是需要耗费大量资源和时间的,开发者应该非常节约的使用线程资源.最好的办法是使用线程池,线程池能够避免当前进行中大量的线程导致操作系统不停的进行线程切换,当线程数 ...
- [转载]ArcGIS Engine 中的多线程使用
ArcGIS Engine 中的多线程使用 原文链接 http://anshien.blog.163.com/blog/static/169966308201082441114173/ 一直都想写 ...
- python中的多线程【转】
转载自: http://c4fun.cn/blog/2014/05/06/python-threading/ python中关于多线程的操作可以使用thread和threading模块来实现,其中th ...
- 拒绝卡顿——在WPF中使用多线程更新UI
原文:拒绝卡顿--在WPF中使用多线程更新UI 有经验的程序员们都知道:不能在UI线程上进行耗时操作,那样会造成界面卡顿,如下就是一个简单的示例: public partial class MainW ...
- java中的多线程——进度2
package src;/*多线程总结:1,进程和线程的概念. |--进程: |--线程:2,jvm中的多线程体现. |--主线程,垃圾回收线程,自定义线程.以及他们运行的代码的位置 ...
- Qt中的多线程编程
http://www.ibm.com/developerworks/cn/linux/l-qt-mthrd/ Qt 作为一种基于 C++ 的跨平台 GUI 系统,能够提供给用户构造图形用户界面的强大功 ...
- 转:MFC中创建多线程
MFC中创建多线程 MFC的多线程函数必须声明为静态的或者是全局函数(不同的在于全局函数不能访问类的私有静态成员,而静态类函数可以):但这样的线程函数只能访问静态的成员变量,要实现访问类的其他成员 ...
- C#中的多线程-入门
概述与概念C#支持通过多线程并行地执行代码,一个线程有它独立的执行路径,能够与其它的线程同时地运行.一个C#程序开始于一个单线程,这个单线程是被CLR和操作系统(也称为“主线程”)自动创建的,并具有多 ...
随机推荐
- Android在如何建立一个WebServer
今天老板交待任务最终完成了,感觉收获颇多,所以写一个关于它的记录,首先,看一下.老板的需求 需求: 希望移动端的用户标识(IMEI)和HTML页面的用户标识(Cookie)连接起来,当中HTML页面可 ...
- CF 460C Present 【DP+】主意
给你n高树花.m日,每天连续浇筑w鲜花.一天一次,花长1高度单位 求m天后.最矮的花最高是多少 最大最小问题能够用二分来解 首先我们能够得到全部花的最矮高度即答案的下界,给这个花浇m天即是答案的上界 ...
- CentOS 如何使用第三方软件库-EPEL与RPMForge、RPMFusion软件库
在CentOS下运行yum install flash-plugin或yum install mplayer的时候,提示库里没有找到这个软件?为什么会这样?因为CentOS是RHEL编译过来的,去掉了 ...
- SQL Server 2005使用OSQL连接出错
错误信息: [SQL Native Client] 命名管道提供程序:无法打开与 Sql Server 的连接[2]. 如下图: 解决方案: 设置Tcp/IP属性,将IP1,IP2,IPALL的TCP ...
- Oracle ORA-01034,ORA-27101,ORA-00600
本机IP地址:192.168.1.163 [oracle@rtest ~]$ sqlplus /nolog SQL*Plus: Release 10.2.0.2.0 - Production on S ...
- atitit.标准时间格式 相互转换 秒数 最佳实践
atitit.标准时间格式 相互转换 秒数 最佳实践 例如00:01:19 转换为秒数 79,,and互相转换 一个思路是使用div 60 mod...只是麻烦的... 更好的方法是使用stamp ...
- HTML<!DOCTYPE> 宣示
在html页面,下面这行代码到底有什么用呢? <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" & ...
- OpenCV在MFC图像控件内显示图像
1.依照文章<OpenCV+MFC显示图像>,完毕配置. 2.创建对应的图像控件,button控件. 3.进行类型转换. 在当前OpenCV2版本号内,图像格式为cv::Mat ,而该格式 ...
- swift的struct本节描述结构的类型
<span style="font-size:24px;">struct David { var x = 0;//一个结构的定义,两个字段x,y var y = 0;/ ...
- table 谷歌下不出现滚动条
<table> </table> <style> table {overflow-y:scroll;max-height:152px; height:auto;} ...