C#线程同步自动重置事件——AutoResetEvent

时间:2023-03-09 03:10:19
C#线程同步自动重置事件——AutoResetEvent

AutoResetEvent对象用来进行线程同步操作,AutoResetEvent类继承waitHandle类。

AutoResetEvent对象有终止和非终止两种状态,终止状态是线程继续执行,非终止状态使线程阻塞,可以调用set和reset方法使对象进入终止和非终止状态。AutoResetEvent顾名思义,其对象在调用一次set之后会自动调用一次reset,进入非终止状态使调用了等待方法的线程进入阻塞状态。

waitHandle对象的waitone可以使当前线程进入阻塞状态,等待一个信号。直到当前 waitHandle对象收到信号,才会继续执行。

set可以发送一个信号,允许一个或多个因为调用waitone而等待线程继续执行,经实验,如果有多个等待的线程,一次set只能让一个线程继续执行。

reset可以使因为调用waitone而等待线程都进入阻塞状态。

下面的例子是启动了两个线程,用AutoResetEvent对象来让他们阻塞或者继续。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; namespace myTest
{
class Program
{
const int numIterations = ;
//initialState 若要一开始就是阻塞的,则设为false,一开始是非阻塞的,则设为true。
static AutoResetEvent myResetEvent = new AutoResetEvent(false);
static int number=; static void Main(string[] args)
{
Thread myReaderThread = new Thread(new ThreadStart(MyReadThreadProc));
myReaderThread.Name = "ReaderThread";
myReaderThread.Start();
Thread myReaderThread2 = new Thread(new ThreadStart(MyReadThreadProc2));
myReaderThread2.Name = "ReaderThread2";
myReaderThread2.Start();
//myResetEvent.Reset(); // 设为终止状态,让 waitone的线程阻塞
for (int i = ; i <= numIterations; i++)
{ Console.WriteLine("Writer thread writing value: {0}", i);
number = i;
//将事件状态设置为终止状态,允许一个或多个等待线程继续。
myResetEvent.Set();
Thread.Sleep();
myResetEvent.Set();
//休息一下,让线程1和2来得及执行
Thread.Sleep(); }
myReaderThread.Abort();
Console.ReadLine();
}
static void MyReadThreadProc()
{
while (true)
{
// 阻止当前线程,直到 Threading.waitHandler 收到一次信号
myResetEvent.WaitOne();
Console.WriteLine("Thread1: {0} reading value: {1}", Thread.CurrentThread.Name, number);
}
}
static void MyReadThreadProc2()
{
while (true)
{
// 阻止当前线程,直到 Threading.waitHandler 收到一次信号
myResetEvent.WaitOne();
         Console.WriteLine(DateTime.Now.ToString());
Console.WriteLine("Thread2:{0} reading value: {1}", Thread.CurrentThread.Name, number);
}
}
}
}

执行结果:

C#线程同步自动重置事件——AutoResetEvent

在结果中可以看到,如果有多个线程等待,每次set之后只有一个线程继续执行,且继续执行的线程是随机的。