随笔分类 - 多线程
1
摘要:C# Dictionary 是线程不安全的,这意味着多线程操作一个共享的Dictionary实例会有问题 不安全代码如下: class _20210306_4 { public void Run() { CancellationTokenSource cts = new CancellationTo
阅读全文
摘要:调用 ConcurrentDictionary 本身的方法和属性可以保证都是线程安全的。但是由于 ConcurrentDictionary 实现了一些接口(例如 ICollection、IEnumerable 和 IDictionary 等),使用这些接口的成员(或者这些接口的扩展方法)不能保证其线
阅读全文
摘要:1 Mutex-互斥体 Mutex可以用于线程同步也可以用于进程同步 构造函数 public Mutex(bool initiallyOwned, string? name, out bool createdNew) initiallyOwned-是否具有互斥体的初始所有权,false-意味着调用构
阅读全文
摘要:Task<T>:任务返回结果类型为T的Task,Task<T>继承Task,Task<T>有Result属性,Result类型为T,而Task无Result属性 Task<T>类似于C#内置的两个委托:有返回值的Func,如Func<T1,T2,T3>代表参数值类型为T1和T2返回值类型为T3的委托
阅读全文
摘要:ReaderWriterLockSlim-多线程读单线程写 当线程A已经获取到ReaderWriterLockSlim实例的读锁(RedLock,UpgradeableReaLock)后,其它线程只能再获取到该ReaderWriterLockSlim实例的读锁,再申请获取写锁会被阻塞 当线程A已获取
阅读全文
摘要:ConfigureAwait(false):当 await 等待完成时,它会尝试在线程池上下文中执行 await 之后的代码 ConfigureAwait(true):当 async 方法内的 await 执行完成时,它会尝试获取之前调用者线程所在的上下文执行方法的剩余部分 在Winform程序中没
阅读全文
摘要:异步方法一般执行流程: await 之前的代码同步运行在调用异步方法的线程里 当运行到await所在行后,调用线程在这里会立即返回,await等待的异步任务会被调度程序重新排队到线程池申请可用的工作线程异步执行 当await异步等待的任务完成后,await之后的代码重新排队从线程池中申请可用工作线程
阅读全文
摘要:Thread.Sleep(n) Sleep 的意思是告诉操作系统自己要休息 n 毫秒,这段时间就让给另一个就绪的线程吧。相比 Yield,可以调度任何处理器的线程使用时间片。在休息的 n 毫秒时间内,即使没有其他就绪线程,自己也不再占用CPU。 当 n=0 的时候,意思是要放弃自己剩下的时间片,但是
阅读全文
摘要:SpinWait是一种混合模式的自旋等待,被设计为先使用用户模式等待一段时间(在用户模式等待时间段内当前线程不会让出cpu的时间片),如果等待还未结束然后会切换到内核模式进行等待(这时线程会让出cpu的时间片给其他线程,会强制产生上下文调度); SpinWait自旋等待的益处: 对于只需要短暂等待的
阅读全文
摘要:volatile关键字指示一个变量是易变的,volatile指示编译器禁止指令重排序,指令按照编码顺序执行,volatile并不保证线程安全性,它只保证任何时候你读取到的都是最新值
阅读全文
摘要:CountdownEvent-在收到特定次数信号后使等待线程继续运行的同步基元 1 CountdownEvent内部使用ManualResetEventSlim来实现信号量同步的 在CountdownEvent源码里有一个ManualResetEventSlim变量,源码如下: 2 Countdow
阅读全文
摘要:Task异步任务里面如果发生了未经处理的异常并不会终止程序的正常运行,如果是Thread创建的线程里发生了异常会终止程序的运行(控制台项目程序测试得出的结论), 由于async异步方法的返回值只能为void、Task和Task<T>所以也可以认为async异步方法产生的异常也不会导致程序的终止 对于
阅读全文
摘要:并发 当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时运行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent) 并行 当系统有一个以上CPU时,则
阅读全文
摘要:对于使用 new Task创建的任务,需要手动调用start方法任务才会开始运行;但是使用async/await异步里的任务不需要手动启动运行 实例 static void Main(string[] args) { Task<string> task = new Task<string>(() =
阅读全文
摘要:进程会等待所有的前台线程完成后再结束本工作;但是如果只剩下后台线程,则会直接结束本工作,不会等待后台线程完成后再结束本工作。 1 new Thread创建的线程 默认情况下使用new Thread()方法创建的线程为前台线程,可以通过手动设置IsBackground属性来创建一个后台线程; 默认前台
阅读全文
摘要:示例代码: #region Lambda表达式传参导致线程参数共享问题 public static void ThreadLambdaPara() { for(int i = 1; i <= 5; i++) { new Thread(() => ThreadMethod(i)).Start(); }
阅读全文
摘要:Task<string>没有使用async标记方法,不能把string返回值自动转换为Task<string> 不使用async改写如下 在该方法前面加上async关键字后就不会有问题,会将string自动转换为Task<string>
阅读全文
摘要:背景 先看下面一段代码,看看运行结果 class Program { static void Main(string[] args) { AccountTest account = new AccountTest(); var tasks = new List<Task>(); var task1
阅读全文
摘要:CAS CAS(比较并交换)是一种无锁算法,lock是对共享资源加了互斥锁; CAS涉及三个操作数,内存地址V(即要修改的值的内存地址)、旧的预期值A和要修改的新值B,当且仅当旧的预期值A与内存地址V上的值一样时才把地址V上的值修改为新值B; CAS伪代码表示如下: do{ 备份内存地址V上的值为旧
阅读全文
摘要:如果多个线程使用同一个AutoResetEvent或者ManualResetEventSlim实例,则可以使用AutoResetEvent和ManualResetEventSlim来实现线程同步; 1 AutoResetEvent 1.1 构造方法 new AutoResetEvent(bool)
阅读全文
1