C#多线程编程(转)
一、使用线程的理由
1、可以使用线程将代码同其他代码隔离,提高应用程序的可靠性。
2、可以使用线程来简化编码。
3、可以使用线程来实现并发执行。
二、基本知识
1、进程与线程:进程作为操作系统执行程序的基本单位,拥有应用程序的资源,进程包含线程,进程的资源被线程共享,线程不拥有资源。
2、前台线程和后台线程:通过Thread类新建线程默认为前台线程。当所有前台线程关闭时,所有的后台线程也会被直接终止,不会抛出异常。
3、挂起(Suspend)和唤醒(Resume):由于线程的执行顺序和程序的执行情况不可预知,所以使用挂起和唤醒容易发生死锁的情况,在实际应用中应该尽量少用。
4、阻塞线程:Join,阻塞调用线程,直到该线程终止。
5、终止线程:Abort:抛出 ThreadAbortException 异常让线程终止,终止后的线程不可唤醒。Interrupt:抛出 ThreadInterruptException 异常让线程终止,通过捕获异常可以继续执行。
6、线程优先级:AboveNormal BelowNormal Highest Lowest Normal,默认为Normal。
三、线程的使用
线程函数通过委托传递,可以不带参数,也可以带参数(只能有一个参数),可以用一个类或结构体封装参数。
namespace Test {class Program{static void Main(string[] args){Thread t1 = new Thread(new ThreadStart(TestMethod));Thread t2 = new Thread(new ParameterizedThreadStart(TestMethod));t1.IsBackground = true;t2.IsBackground = true;t1.Start();t2.Start("hello");Console.ReadKey();}public static void TestMethod(){Console.WriteLine("不带参数的线程函数");}public static void TestMethod(object data){string datastr = data as string;Console.WriteLine("带参数的线程函数,参数为:{0}", datastr);}} }
四、线程池
由于线程的创建和销毁需要耗费一定的开销,过多的使用线程会造成内存资源的浪费,出于对性能的考虑,于是引入了线程池的概念。线程池维护一个请求队列,线程池的代码从队列提取任务,然后委派给线程池的一个线程执行,线程执行完不会被立即销毁,这样既可以在后台执行任务,又可以减少线程创建和销毁所带来的开销。
线程池线程默认为后台线程(IsBackground)。
namespace Test {class Program{static void Main(string[] args){//将工作项加入到线程池队列中,这里可以传递一个线程参数ThreadPool.QueueUserWorkItem(TestMethod, "Hello");Console.ReadKey();}public static void TestMethod(object data){string datastr = data as string;Console.WriteLine(datastr);}} }
五、Task类
使用ThreadPool的QueueUserWorkItem()方法发起一次异步的线程执行很简单,但是该方法最大的问题是没有一个内建的机制让你知道操作什么时候完成,有没有一个内建的机制在操作完成后获得一个返回值。为此,可以使用System.Threading.Tasks中的Task类。
构造一个Task<TResult>对象,并为泛型TResult参数传递一个操作的返回类型。
namespace Test {class Program{static void Main(string[] args){Task<Int32> t = new Task<Int32>(n => Sum((Int32)n), 1000);t.Start();t.Wait();Console.WriteLine(t.Result);Console.ReadKey();}private static Int32 Sum(Int32 n){Int32 sum = 0;for (; n > 0; --n)checked{ sum += n;} //结果太大,抛出异常return sum;}} }
一个任务完成时,自动启动一个新任务。
一个任务完成后,它可以启动另一个任务,下面重写了前面的代码,不阻塞任何线程。
namespace Test {class Program{static void Main(string[] args){Task<Int32> t = new Task<Int32>(n => Sum((Int32)n), 1000);t.Start();//t.Wait();Task cwt = t.ContinueWith(task => Console.WriteLine("The result is {0}",t.Result));Console.ReadKey();}private static Int32 Sum(Int32 n){Int32 sum = 0;for (; n > 0; --n)checked{ sum += n;} //结果溢出,抛出异常return sum;}} }
六、委托异步执行
委托的异步调用:BeginInvoke() 和 EndInvoke()
namespace Test {public delegate string MyDelegate(object data);class Program{static void Main(string[] args){MyDelegate mydelegate = new MyDelegate(TestMethod);IAsyncResult result = mydelegate.BeginInvoke("Thread Param", TestCallback, "Callback Param");//异步执行完成string resultstr = mydelegate.EndInvoke(result);}//线程函数public static string TestMethod(object data){string datastr = data as string;return datastr;}//异步回调函数public static void TestCallback(IAsyncResult data){Console.WriteLine(data.AsyncState);}} }
七、线程同步
1)原子操作(Interlocked):所有方法都是执行一次原子读取或一次写入操作。
2)lock()语句:避免锁定public类型,否则实例将超出代码控制的范围,定义private对象来锁定。
3)Monitor实现线程同步
通过Monitor.Enter() 和 Monitor.Exit()实现排它锁的获取和释放,获取之后独占资源,不允许其他线程访问。
还有一个TryEnter方法,请求不到资源时不会阻塞等待,可以设置超时时间,获取不到直接返回false。
4)ReaderWriterLock
当对资源操作读多写少的时候,为了提高资源的利用率,让读操作锁为共享锁,多个线程可以并发读取资源,而写操作为独占锁,只允许一个线程操作。
5)事件(Event)类实现同步
事件类有两种状态,终止状态和非终止状态,终止状态时调用WaitOne可以请求成功,通过Set将时间状态设置为终止状态。
1)AutoResetEvent(自动重置事件)
2)ManualResetEvent(手动重置事件)
6)信号量(Semaphore)
信号量是由内核对象维护的int变量,为0时,线程阻塞,大于0时解除阻塞,当一个信号量上的等待线程解除阻塞后,信号量计数+1。
线程通过WaitOne将信号量减1,通过Release将信号量加1,使用很简单。
7)互斥体(Mutex)
独占资源,用法与Semaphore相似。
8)跨进程间的同步
通过设置同步对象的名称就可以实现系统级的同步,不同应用程序通过同步对象的名称识别不同同步对象。
转载于:https://www.cnblogs.com/yellowcool/p/7444336.html
C#多线程编程(转)相关推荐
- C 多线程编程之在类中使用多线程(thread)的方法
一.thread的基本用法 参见C++使用thread类多线程编程 . 二.类外使用多线程,访问类的成员 这几种方式,新建线程都是在类外,然后通过把友元函数或者成员函数作为thread参数. #inc ...
- Linux多线程管理: 多线程编程
多线程编程 mind-Mapping保存有一下导图的xmind文件,可直接获取 互斥变量 互斥对象 ptrhead相关接口 条件变量 future异步访问类 async类 promise类 packa ...
- [转]Linux 的多线程编程的高效开发经验
Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多线程 API 有一些细微和隐晦的差别.不注意这些 Linux 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断.本文中我们 ...
- Java多线程编程实战:模拟大量数据同步
背景 最近对于 Java 多线程做了一段时间的学习,笔者一直认为,学习东西就是要应用到实际的业务需求中的.否则要么无法深入理解,要么硬生生地套用技术只是达到炫技的效果. 不过笔者仍旧认为自己对于多线程 ...
- 20180829-Java多线程编程
Java 多线程编程 Java给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分. 程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 多线程是多任务的一种特 ...
- java多线程编程01---------基本概念
一. java多线程编程基本概念--------基本概念 java多线程可以说是java基础中相对较难的部分,尤其是对于小白,次一系列文章的将会对多线程编程及其原理进行介绍,希望对正在多线程中碰壁的小 ...
- 如何实现C++中的多线程编程
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文整理自:知乎用户yikang知乎专栏 Part 1. 基本概念 ...
- 多线程编程有什么用途_C++ 多线程编程 (一)
What is thread? In computer science, a thread of execution is the smallest sequence of programmed in ...
- 多线程编程1-NSThread
前言 每个iOS应用程序都有个专门用来更新显示UI界面.处理用户触摸事件的主线程,因此不能将其他太耗时的操作放在主线程中执行,不然会造成主线程堵塞(出现卡机现象),带来极坏的用户体验.一般的解决方案就 ...
- Linux下不使用qt自带sleep,Linux下Qt多线程编程
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 作者:武汉华嵌嵌入式培训中心 技术部 以下和大家分享Linux平台下Qt两种多线程编程的方式: 1.使用Linux平台下的线程函数.以下是给出的代码片段: ...
最新文章
- winform改变控件的外形
- Java机器学习库ML之十一线性SVM
- Simulink中进行电容充放电的一种简单仿真
- 网站前端和后台性能优化24
- Beta版本测试报告
- Linux驱动设置log打印开关
- 调通sina33下的AP6212A0(WIFI+BT)(V1.1版本)
- win7装sql2000找不到服务器,Win7怎么正确安装使用sql2000教程
- c语言专业认知实践报告怎么写,c语言实践报告心得范文
- 快捷键:浏览器关闭网页的快捷键,切换网页的快捷键,打开网页的快捷键
- word 去除页眉默认的横线及python操作分析
- html5 audio音乐播放,循环播放等9款播放器
- 语音特征MFCC和PLP
- uniapp自定义搜索组件实现全部功能
- 阿里总部对外解密双11超级工程背后的数据库技术
- Tikz作图教程:pgfplots宏包—三维数据散点图,完美重构文献美图
- android性能排行,2018年11月Android手机性能排行 麒麟980碾压高通蝉联前三
- 智美2.0 文字格式化
- 解决“正在连接****|::|:443...失败:拒绝连接”问题
- 面试分析《疯狂Python讲义》PDF代码+《Python核心编程第3版》PDF代码问题