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和操作系统(也称为“主线程”)自动创建的,并具有多 ...
随机推荐
- HUNNU11352:Digit Solitaire
Problem description Despite the glorious fall colors in the midwest, there is a great deal of time t ...
- 从PCI上读取数据 线程和定时器效率
从PCI上读取数据 线程和定时器效率 线程: mythread=AfxBeginThread(StartContinuous,(LPVOID)1,THREAD_PRIORITY_NORMAL,0,CR ...
- Spring 事情具体详尽的解释
一.Spring事务管理 1. Spring事务管理机制 三个核心部分 1) PlatformTransactionManager 平台的事务管理器 commit 提交事务.rollback ...
- oracle12c(oracle12.1.0.1.0)安装指南--实测OEL5.9(RH5)
[root@oel ora12c]# uname -a Linux oel 2.6.39-300.26.1.el5uek #1 SMP Thu Jan 3 18:31:38 PST 2013 x86_ ...
- vs修错小知识,相当于我自己的笔记,需要的人可以看下
在出现这种外部错误时,首先得检查你自己的的类的方法是否都以及实现了,我就是出现没有实现某些方法所以报出这个错误!!! 结果是onExit()方法我定义了没有去实现它. (待续)
- Hibernate4.3.9Final常见问题汇总
hibernate4下一个可用的hibernate.properties: jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql ...
- 创Wcf案例数据服务
首先,创建实体类: using System; using System.Linq; using System.Collections.Generic; using System.Data.Servi ...
- 安卓的sqlite增删改
基于安卓的sqlite增删改,笔记学习: 1.使用LinearLayout 布局生成,增删改的页面如图 代码布局如下: <LinearLayout xmlns:android="htt ...
- 玩转web之servlet(六)---session介绍及简单使用(登录验证中保存信息)
在浏览器与服务器进行交互时,往往需要把涉及到的一些数据保存下来,这时就需要使用cookie或session进行状态管理. 这篇文章先来说说session怎么用,首先在servlet中创建一个sessi ...
- bash组织成树数据结构
君子也非独占,善假于物!bash也因此.昨天晚上,今天早上世界杯很精彩.晚上醒来看到不断地居住的电话.早上没有喝的水开始赞赏在英国和意大利的对决.也TM精彩,最后生下了罗马文化.意大利伊特鲁里亚文化获 ...