WaitHandle是一个抽象类,用于等待一个信号的设置。可以等待不同的信号,因为WaitHandle是一个基类,可以从中派生一些类
如下案例:
public delegate int TakesAWhileDelegate(int x, int ms);
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
TakesAWhileDelegate dl = TakesAWhile;
IAsyncResult ar = dl.BeginInvoke(1, 3000, null, null);
while (true)
{
Console.WriteLine(".");
if (ar.AsyncWaitHandle.WaitOne(50))
{
Console.WriteLine("现在可以得到结果");
break;
}
}
int result = dl.EndInvoke(ar);
Console.WriteLine($"result:{ result}");
sw.Stop();
var times = sw.Elapsed.TotalSeconds;
Console.WriteLine("所消耗时间:" + times);
Console.ReadLine();
}
public static int TakesAWhile(int x, int ms)
{
Task.Delay(ms).Wait();
return 42;
}
使用WaitHandle基类可以等待一个信号的出现(Waitone()方法)、等待必须发出信号的多个对象(WaitAll()方法),或者等待多个对象中的一个(WaitAny()方法)。
Mutex类
Mutex是.net framework中提供跨多个进程同步访问的一个类。它非常类似于Monitor类,因为它们都只有一个线程能拥有锁定。只有一个线程能获得互斥锁定,访问受互斥保护的同步代码区域。
Mutex定义的范围内只有一个线程可以访问,其它同一时间访问的线程会被过滤掉无法访问。
private static Mutex mut = new Mutex();
private const int numIterations = 1;
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Task[] tasks = new Task[5];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = Task.Factory.StartNew(ThreadProc, i);
}
Task.WaitAll(tasks);
sw.Stop();
var times = sw.Elapsed.TotalSeconds;
Console.WriteLine("所消耗时间:" + times);
//另一种验证程序本地是否启动的方式
//bool flag;
//Mutex mutex = new Mutex(false, "CustomApp", out flag);
//if (!flag)
//{
// Console.WriteLine("改程序本地以打开");
//}
Console.ReadLine();
}
private static void ThreadProc(object name)
{
for (int i = 0; i < numIterations; i++)
{
UseResource(name?.ToString());
}
}
private static void UseResource(string name)
{
Console.WriteLine("任务{0}正在请求互斥", name);
Console.WriteLine();
if (mut.WaitOne(1000))
{
Console.WriteLine("任务{0}已进入保护区域", name);
Thread.Sleep(2000);
Console.WriteLine("任务{0}离开保护区", name);
mut.ReleaseMutex();
Console.WriteLine("任务{0}已经释放了互斥", name);
}
else
{
Console.WriteLine("任务{0}不会获得互斥", name);
}
}
下一章节阐述Semaphore类的使用,以及其它同步方式