C# 线程相关
- AutoResetEvent类 ManualResetEvent类
两者区别在于前者.WaitOne()方法,会立即执行Reset重置信号
eg:using System.Threading;
AutoResetEvent _next = new AutoResetEvent(false);
_next .Set();//通知下一个执行 _next.WaitOne();//等待通知if(_next .WaitOne()) 和 _next.WaitOne();使用中差别不大
- SpinWait 类
eg: using System.Threading;
SpinWait _spainWait = new SpinWait();
int WaitContinue = 0;while(Thread.VolatileRead(ref WaitContinue) != 1)
_spainWait.SpinOnce();// 自旋等待一次
//在其他线程中可以执行
Thread.VolatileWrite(ref WaitContinue,1);//保证一致性 修改参数
- new Thread(MyMethod).Start();//启动新线程
- SemaphoreSlim 类
//SemaphoreSlim ss= new SemaphoreSlim(0, 4); // (初始数量,最大数量)
SemaphoreSlim ss = new SemaphoreSlim(1);//定义信号量
//ss.CurrentCount 获取信号量数量
//进入一个减少一个,0会等待线程阻塞
for(int i=0;i<10;i++){
Task.Run(() =>
{ss.Wait(); // 调用 Wait() 方法,标记等待进入信号量
try{
//执行内容
......
}finally{
ss.Release();//释放当前信号量之前的信号量
}
}
}
- volatile关键字
用法和const一样,被设计于用于多个线程访问和修改的变量,不适用volatile会出现,要么无法编写多线程程序,要么编译器失去大量优化的机会。 - CancellationTokenSource 线程控制
private SemaphoreSlim returnToMain = new SemaphoreSlim(0,1);
private CancellationTokenSource cts = new CancellationTokenSource();//另一个方法如果在等待
while(true){
returnToMain.Wait(cts.Token);
}
//当前方法可以直接停止
cts.Cancel();//主线程结束,子线程也结束
- Barrier类
//一组任务并行地运行一连串的阶段,但是每一个阶段都要等待所有其他任务都完成前一阶段之后才能开始,你一通过Barrier实例来同步这一类协同工作。
//Barrier初始化后,将等待特定数量的信号到来,这个数量在Barrier初始化时指定,在所指定的信号个数已经到来后,Barrier将执行一个指定的动作,这个动作也是在Barrier初始化时指
定。
//Barrier在执行动作过后,将会重置,这时又将等待特定数量的信号到来,再执行指定动作Barrier bar = new Barrier(2);
public void EvenNumber(){
for(int i =0;i<10;i++){
if(i%2==0){
console.Wirete(i);
}
bar.SingnalAndWait();
}
}
public void OddNumber(){
for(int i =0;i<10;i++){
if(i%2!=0){
console.Wirete(i);
}
bar.SingnalAndWait();
}
}
//多线程同时调用会依次输出偶数和奇数