随笔分类 - 20-多线程和异步
1
摘要:一. CancellationToken终止信号 CancelAfter()超时后发出取消信号 Cancel() 发出取消信号 { CancellationTokenSource cts = new(); cts.CancelAfter(4000); //4s后取消 await Download1A
阅读全文
摘要:一. 深度剖析 准备: 先给VS安装一个插件ILSpy,这样更容易反编译代码进行查看,另外要注意反编译async和await的时候,要把C#代码版本改为4.0哦。 1.什么是状态机 (1).含义:通常我们所说的状态机(State Machine)指的是有限状态自动机的简称,是现实事物运行规则抽象而成
阅读全文
摘要:一. 再谈异步 1. 什么是异步方法 使用者发出调用指令后,不需要等待返回值,就可以继续执行后面的代码,异步方法基本上都是通过回调来通知调用者。 (PS:线程池是一组已经创建好的线程,随用随取,用完了不是销毁线程,然后放到线程池中,供其他人用) 异步方法可以分为两类: (1).CPU-Bound(计
阅读全文
摘要:一. 同步VS异步 1. 同步 VS 异步 VS 多线程 同步方法:调用时需要等待返回结果,才可以继续往下执行业务 异步方法:调用时无须等待返回结果,可以继续往下执行业务 开启新线程:在主线程之外开启一个新的线程去执行业务 同步方法和异步方法的本质区别: 调用时是否需要等待返回结果才能继续执行业务
阅读全文
摘要:一. 背景 在刚接触开发的头几年里,说实话,根本不考虑多线程的这个问题,貌似那时候脑子里也有没有多线程的这个概念,所有的业务都是一个线程来处理,不考虑性能问题,当然也没有考虑多线程操作一条记录存在的并发问题,后面随着处理的系统业务越来越复杂,多线程再也回避不了了,也就借此机会深入研究了一下.Net中
阅读全文
摘要:一. 四大并发集合类 背景:我们目前使用的所有集合都是线程不安全的 。 A. ConcurrentBag:就是利用线程槽来分摊Bag中的所有数据,链表的头插法,0代表移除最后一个插入的值. (等价于同步中的List) B. ConcurrentStack:线程安全的Stack是使用Interlock
阅读全文
摘要:一. 监视锁(Monitor和lock) 1. Monitor类,限定线程个数的一把锁,两个核心方法: Enter:锁住某个资源。 Exit:退出某一个资源。 测试案例:开启5个线程同时对一个变量进行自增操作,结果变量有序的输出,说明该锁同时只允许一个线程访问。 但是写法很麻烦,每次都要try-ca
阅读全文
摘要:一. 整体介绍 温馨提示:内核模式锁,在不到万不得已的情况下,不要使用它,因为代价太大了,有很多种替代方案。 内核模式锁包括: ①:事件锁 ②:信号量 ③:互斥锁 ④:读写锁 ⑤:动态锁 二. 事件锁 事件锁包括: A. 自动事件锁(AutoResetEvent) 使用场景:可以用此锁实现多线程环境
阅读全文
摘要:一. 锁机制的背景介绍 本章节,将结合多线程来介绍锁机制, 那么问题来了,什么是锁呢? 为什么需要锁? 为什么要结合多线程来介绍锁呢?锁的使用场景又是什么呢? DotNet中又有哪些锁呢? 在接下来的几个章节中,将陆续解答这些问题。 PS: 多个线程对一个共享资源进行使用的时候,会出问题, 比如实际
阅读全文
摘要:一. async和await简介 PS:简介 1. async和await这两个关键字是为了简化异步编程模型而诞生的,使的异步编程跟简洁,它本身并不创建新线程,但在该方法内部开启多线程,则另算。 2. 这两个关键字适用于处理一些文件IO操作。 3. 好处:代码简介,把异步的代码写成了同步的形式,提高
阅读全文
摘要:一. 并行编程 1. 区分串行编程和串行编程 ①. 串行编程:所谓的串行编程就是单线程的作用下,按顺序执行。(典型代表for循环 下面例子从1-100按顺序执行) ②. 并行编程:充分利用多核cpu的优势,同时开启多个线程并行执行。(典型代表Parallel.For循环 下面例子从1-100无序执行
阅读全文
摘要:一. Task的各种返回值-Task<TResult> PS: 在前面章节,我们介绍了Task类开启线程、线程等待、线程延续的方式,但我们并没有关注这些方式的返回值,其实他们都是有返回值的Task<TResult>,然后可以通过Task的实例调用Result属性来获取这个返回值。 下面我们分三类来介
阅读全文
摘要:一. 传统的线程取消 所谓的线程取消,就是线程正在执行的过程中取消线程任务。 传统的线程取消,是通过一个变量来控制,但是这种方式,在release模式下,被优化从cpu高速缓存中读取,而不是从内存中读取,会造成主线程无法执行这一个bug。 PS: 通过上面的代码看可以看出来,传统模式的线程取消,在排
阅读全文
摘要:一. 整体说明 揭秘: 该章节的性质和上一个章节类似,也是一个扩展的章节,主要来研究Task类下的实例方法ContinueWith中的参数TaskContinuationOptions。 通过F12查看TaskContinuationOptions的源码,知道主要有这么几个参数: ①. LazyCa
阅读全文
摘要:一. 整体说明 揭秘: 通过F12查看Task类的源码(详见下面的截图),发现Task类的构造函数有有一个参数为:TaskCreationOptions类型,本章节可以算作是一个扩展章节,主要就来研究TaskCreationOptions类的作用。 该类主要用来处理父子线程之间的关系,重要的几个参数
阅读全文
摘要:一. 背景 揭秘: 在前面的章节介绍过,Task出现之前,微软的多线程处理方式有:Thread→ThreadPool→委托的异步调用,虽然也可以基本业务需要的多线程场景,但它们在多个线程的等待处理方面、资源占用方面、线程延续和阻塞方面、线程的取消方面等都显得比较笨拙,在面对复杂的业务场景下,显得有点
阅读全文
摘要:一. ThreadPool简介 ThreadPool简介:ThreadPool是一个线程池,当你需要开启n个线程时候,只需把这个指令抛给线程池,它将自动分配线程进行处理,它诞生于.Net 2.0时代。 ThreadPool与Thread的区别: ①:Thread每开启一个异步任务,就需要使用一个Th
阅读全文
摘要:一. Thread及其五大方法 Thread是.Net最早的多线程处理方式,它出现在.Net1.0时代,虽然现在已逐渐被微软所抛弃,微软强烈推荐使用Task(后面章节介绍),但从多线程完整性的角度上来说,我们有必要了解下N年前多线程的是怎么处理的,以便体会.Net体系中多线程处理方式的进化。 Thr
阅读全文
摘要:一. 再谈委托 1. 委托是一个关键字为delegate的自定义类型,通过委托可以把方法以参数的形式传递给另外一个方法,实现插件式的开发模式; 同时调用委托的时候,委托所包含的所有方法都会被实现。 2. 委托的发展历史:new实例化传递方法→直接等于方法名→delegate匿名方法→省略delega
阅读全文
摘要:一. 背景 在刚接触开发的头几年里,说实话,根本不考虑多线程的这个问题,貌似那时候脑子里也有没有多线程的这个概念,所有的业务都是一个线程来处理,不考虑性能问题,当然也没有考虑多线程操作一条记录存在的并发问题,后面随着处理的系统业务越来越复杂,多线程再也回避不了了,也就借此机会深入研究了一下.Net中
阅读全文
1