c# 多线程高级
2020-09-03 13:52:54 0 举报
AI智能生成
.net 多线程理解
作者其他创作
大纲/内容
Thread
Start、Suspend、Resume、Intterupt、Abort
数据槽-线程可见性
AllocateNamedDataSlot命名槽位和AllocateDataSlot未命名槽位 解决线程竞用资源共享问题
利用特性[ThreadStatic] 解决线程竞用资源共享问题
利用ThreadLocal线程的本地存储, 解决线程竞用资源共享问题(线程可见性)
内存栅栏-线程共享资源
利用VolatileRead/Write方法进行处理
ThreadPool
QueueUserWorkItem (线程开启)排入队列以便开启异步线程
ManualResetEvent类和WaitOne (线程等待)
设置、获取工作线程和IO线程(最大、最小、可用值,GetMaxThreads、GetMinThreads、GetAvailableThreads)
定时类(RegisterWaitForSingleObject、Timer类)
Task
4种启动方式
实例化的方式+Start方法启动
Task下Run方法启动
TaskFactory工厂的StartNew方法启动
Task下的同步方法RunSynchronously 启动
Task 线程等待和延续
Wait:针对单个Task的实例,可以task1.wait进行线程等待.
WaitAny:执行的线程等待其中任何一个线程执行完毕即可执行(如果主线程执行,则卡主线程)
WhenAny:与下面ContinueWith配合执行,当传入的线程中任何一个线程执行完毕,继续执行ContinueWith中的任务(属于开启新线程,不卡主线程)
WhenAll:与下面ContinueWith配合执行,当传入的线程中所有线程执行完毕,继续执行ContinueWith中的任务(属于开启新线程,不卡主线程)
ContinueWith:和上面WhenAny和WhenAll配合使用
TaskFactory的线程等待
ContinueWhenAny:等价于Task的WhenAny+ContinueWith
ContinueWhenAll:等价于Task的WhenAll+ContinueWith
CancellationTokenSource 实现任务取消
取消任务的同时触发一个函数
延时取消
方案一:CancelAfter方法
方案二:CancellationTokenSource构造函数(不再需要Cancel方法了)。
3. 组合取消(利用CreateLinkedTokenSource构建CancellationTokenSource的组合体,其中任何一个体取消,则组合体就取消)
CancellationToken类监控取消
Task的各种返回值-Task<TResult>
线程开启类的返回值
线程延续类的返回值
线程条件延续类的返回值
串行编程Parallel
For
ForEach
Invoke
async和await
用法
情况1:当只有async,没有await时,方法会有个警告,和普通的多线程方法没有什么区别,不存在线程等待的问题。
情况2:不推荐void返回值,使用Task来代替Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行。
情况3:async Task == async void。 区别:Task和Task<T>能够使用await, Task.WhenAny, Task.WhenAll等方式组合使用,async Void 不行
情况4和情况5:说明要使用子线程中的变量,一定要等子线程执行结束后再使用。
使用套路
常见的异步方法
HttpClient类
EF中DbContext类
文件相关中的
几个规则和约定
async封装的方法中,可以有多个await,这里的await代表等待该行代码执行完毕
我们通常自己封装的方法也要以Async结尾,方便识别
异步返回类型主要有三种:Task<T> 、Task、Void
Task<T>, 处理含有返回值的异步方法,通过 .Result 等待异步方法执行完,且获取到返回值
Task:调用方法不需要从异步方法中取返回值,但是希望检查异步方法的状态,那么可以选择可以返回 Task 类型的对象。不过,就算异步方法中包含 return 语句,也不会返回任何东西
子主题
异步方法
CPU-Bound(计算密集型任务):以线程为基础,具体是用线程池里的线程还是新建线程,取决于具体的任务量
I/O-Bound(I/O密集型任务):是以windows事件为基础(可能调用系统底层api),不需要新建一个线程或使用线程池里面的线程来执行具体工作,不涉及到使用系统原生线程。
状态机分析
锁机制
用户模式锁
异变结构
互锁
Increment:自增操作
Decrement:自减操作
Add: 增加指定的值
Exchange: 赋值
CompareExchange: 比较赋值
旋转锁
内核模式锁
事件锁
自动事件锁(AutoResetEvent)核心方法:WaitOne和Set
手动事件锁(ManualResetEvent) 核心方法:WaitOne和Set
信号量
互斥锁
读写锁
动态锁
监视锁(Monitor和lock)
Monitor类,限定线程个数的一把锁,两个核心方法:Enter:锁住某个资源 Exit:退出某一个资源
lock语法糖
混合锁
ManualResetEventSlim
SemaphoreSlim
ReaderWriterLockSlim
四大并发集合类
ConcurrentBag 就是利用线程槽来分摊Bag中的所有数据,链表的头插法,0代表移除最后一个插入的值.
ConcurrentStack 线程安全的Stack是使用Interlocked来实现线程安全, 而没有使用内核锁
ConcurrentQueue 队列的模式,先进先出
ConcurrentDictionary 字典的模式
0 条评论
下一页