C#任务同步

时间:2023-03-09 03:29:15
C#任务同步
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using static System.Console; //任务同步
//1.lock 锁定一个引用类型的变量
/*死锁
lock (_s1)
{
lock (_s2)
{}
} lock (_s2)
{
lock (_s1)
{}
}
*/
//2.Interlocked类,更快但只支持少数几种的操作
//public int State
//{
// get
// {
// lock (this)
// {
// return ++_state;
// }
// }
//}
//相当于
//public int State
//{
// get
// {
// return Interlocked.Increment(ref _state);
// }
//} //3.Monitor类
//4.SpinLock结构,传递时需加引用,不然结构会以值传递
// 如果有大量锁定,如列表的每一个节点都有一个锁定,且锁定时间非常短,SpinLock结构就很有用
// 它与Monitor类似,Enter TryEnter Exit //5.WaitHandle 抽象基类 用于等待一个信号(WaitOne() WaitAll() ...)
//6.Mutex类 操作系统能识别有名称的互斥,可以跨线程,如果没有指定名称则不在不同的进程之间共享
//7.Semaphore类 非常类似于互斥,区别是它可以同时由多个线程使用,是一种计数的互斥
//8.Event类 事件与互斥和信号量一样,也是一个系统范围内的资源同步方法
// ManualResetEvent AutoResetEvent ManualResetEventSlim CountdownEvent
//9.Barrier类 ReaderWriterLockSlim类 //10.Timer类
// Threading中的Timer 基于XAML应用程序的DispatcherTimer namespace ConsoleApp
{
public class StateObject
{
private int _state = ;
private object _sync = new object(); public void ChangeState(int loop)
{ lock (_sync)//方法2.
{
if (_state == )
{
_state++;
Trace.Assert(_state == ,
$"Race condition occured after {loop} loops");
}
_state = ;
}
} }
class Program
{
static void Main(string[] args)
{
//RaceCondition(); object o = new object();
lock (o) { }
//lock由编译器解析为Monitor类
Monitor.Enter(o);
try { }
finally { Monitor.Exit(o); } //Monitor可以设置等待时间
bool _lockTaken = false;
Monitor.TryEnter(o, , ref _lockTaken);
if (_lockTaken)//get the lock
{
try { }
finally { Monitor.Exit(o); }
}
else { } //互斥
bool createNew;
//第3个为输出参数,接收一个表示互斥是否为新建的布尔值,
//如果(createNew)返回为false就表示互斥已经定义
var mutex = new Mutex(false, "ProCSharpMutex", out createNew); if (mutex.WaitOne())
{
try { }
finally { mutex.ReleaseMutex(); }
}
else
{
//some problem happened while waiting
} //信号量
int taskCount = ;
int semaphoreCount = ;
var semaphore = new Semaphore(semaphoreCount-, semaphoreCount);//初始请求数 最大请求数
try
{
int preCount = semaphore.Release();
WriteLine($"preCount: {preCount}");
}
catch (Exception) { } var tasks = new Task[taskCount];
for (int i = ; i < taskCount; ++i)
{
tasks[i] = Task.Run(() => TaskMain(semaphore));
}
Task.WaitAll(tasks);
WriteLine("All tasks finished"); //事件
AutoResetEvent autoEvent = new AutoResetEvent(false);
autoEvent.Reset();
autoEvent.Set(); autoEvent.WaitOne(); //Timer
using (var timer1 = new Timer(TimeAction, null, /*TimeSpan.FromSeconds(0)*/, /*TimeSpan.FromSeconds(3)*/))
{
Task.Delay().Wait();
} ReadKey();
} public static void RaceCondition()
{
var state = new StateObject();
//开启2个Task
for (int i = ; i < ; ++i)
{
Task.Run(() =>
{
int j = ;
while (true)
{
lock (state)//方法1.
{
state.ChangeState(j++);
}
}
});
}
} public static void TaskMain(Semaphore semaphore)
{
bool isComplete = false;
while(!isComplete)
{
if (semaphore.WaitOne())//等到 计数-1
{
try
{
WriteLine($"Task {Task.CurrentId} locks the semaphore");
Task.Delay().Wait();
}
finally
{
WriteLine($"Task {Task.CurrentId} release the semaphore");
semaphore.Release(); //释放 计数+1
isComplete = true;
}
}
else
{
WriteLine($"Timeoue for task {Task.CurrentId}; wait again");
}
}
} private static void TimeAction(object o)
{
WriteLine($"System.Threading.Timer {DateTime.Now:T}");
} }
}