最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也简要提了一下System.Threading.WaitHandle.WaitOne 、System.Threading.WaitHandle.WaitAny和System.Threading.WaitHandle.WaitAll ,下面我们一最初学者的角度来看,多线程之间的同步。
假设有这样的一个场景,主线程开了一个子线程,让子线程等着,等主线程完成了某件事情时再通知子线程去往下执行,这里关键就在于这个怎让子线程等着,主线程怎通知子线程,一般情况下我们不难想到用一个公共变量,于是咱们就有了下面的代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace AutoResetEventTest
{
class Class1
{
static bool flag = true;
static void DoWork()
{
Console.WriteLine(" worker thread started, now waiting on event...");
while (flag)
{
}
Console.WriteLine(" worker thread reactivated, now exiting...");
}
static void Main()
{
Console.WriteLine("main thread starting worker thread...");
Thread t = new Thread(DoWork);
t.Start();
Console.WriteLine("main thrad sleeping for 1 second...");
Thread.Sleep(1000);
Console.WriteLine("main thread signaling worker thread...");
flag = false;
}
}
}
虽然目的达到了,但是看着这代码就纠结,下面该是我们的主角上场了,AutoResetEvent 和 ManualResetEvent,关于这两者我们暂且认为是差不多了,稍后我会介绍他们的不同,这里以AutoResetEvent为例,其实很多官方的说法太过于抽象,这里通俗地讲,可以认为AutoResetEvent就是一个公共的变量(尽管它是一个事件),创建的时候可以设置为false,然后在要等待的线程使用它的WaitOne方法,那么线程就一直会处于等待状态,只有这个AutoResetEvent被别的线程使用了Set方法,也就是要发通知的线程使用了它的Set方法,那么等待的线程就会往下执行了,Set就是发信号,WaitOne是等待信号,只有发了信号,等待的才会执行。如果不发的话,WaitOne后面的程序就永远不会执行。好下面看用AutoResetEvent改造上面的程序:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace AutoResetEventTest
{
class Class2
{
static AutoResetEvent mEvent=new AutoResetEvent(false);
//static ManualResetEvent mEvent = new ManualResetEvent(false);
static void DoWork()
{
Console.WriteLine(" worker thread started, now waiting on event...");
mEvent.WaitOne();
Console.WriteLine(" worker thread reactivated, now exiting...");
}
static void Main()
{
Console.WriteLine("main thread starting worker thread...");
Thread t = new Thread(DoWork);
t.Start();
Console.WriteLine("main thrad sleeping for 1 second...");
Thread.Sleep(1000);
Console.WriteLine("main thread signaling worker thread...");
mEvent.Set();
}
}
}










