【转载】浅谈AutoResetEvent的用法
转载地址:http://hi.baidu.com/iaskall/blog/item/1938e00045f87012738b6526.html
今天在看一段DEMO代码的时候发现AutoResetEvent被反复用到,在MSND中查了资料同时到在网上搜到了一个很简短的例子,这个例子帮我理解AutoResetEvent的用法起了不少辅助作用,这里贴出来,希望对大家理解有所帮助:
(代码都已经在VS2005中成功调试通过,注释是我的理解,只能起参考作用,呵呵)
AutoResetEvent myResetEvent = new AutoResetEvent(false);
MSDN中讲到,若要将初始状态设置为终止,则为 true;若要将初始状态设置为非终止,则为 false
小女子的理解:如过设置true,也就是说这个Event回自动Reset,那么myResetEvent.WaitOne()就能够在程序一启动就获得运行权;就相当于一启动程序就自动运行了一次myResetEven.Set();
反之,就要等myResetEven.Set()成功运行后,myResetEven.WaitOne()才能够获得运行机会;
这里我做个实验给大家看,大家会看到,在设置为true的时候会首先看到ReaderThread reading value运行,然后才是Writer thread wrirting出现:
今天在看一段DEMO代码的时候发现AutoResetEvent被反复用到,在MSND中查了资料同时到在网上搜到了一个很简短的例子,这个例子帮我理解AutoResetEvent的用法起了不少辅助作用,这里贴出来,希望对大家理解有所帮助:
(代码都已经在VS2005中成功调试通过,注释是我的理解,只能起参考作用,呵呵)
using System;
using System.Threading;
namespace AutoResetEvent_Examples
{
class MyMainClass
{
//初始的时候是没有信号的,这里的意思是指参数false
const int numIterations = 100; //重复次数设置多少都无所谓,为让大家看清楚设置了100
static AutoResetEvent myResetEvent = new AutoResetEvent(false);
static int number;
static void Main()
{
//创建并开始一个线程。
Thread myReaderThread = new Thread(new ThreadStart(MyReadThreadProc));
myReaderThread.Name = "ReaderThread";
myReaderThread.Start();
for (int i = 1; i <= numIterations; i++)
{
Console.WriteLine("Writer thread writing value: {0}", i);
number = i;
//发信号,说明值已经被写进去了。这里的意思是说Set是一个发信号的方法。
myResetEvent.Set();
//让每次循环当中有些间隔,没有其他作用,可以注释掉
Thread.Sleep(1000);
}
//终止阅读线程。
myReaderThread.Abort();
}
static void MyReadThreadProc()
{
while (true)
{
//在数据被作者写入之前不会被读者读取
//在上次读取之前至少有一次。
myResetEvent.WaitOne();
Console.WriteLine("{0} reading value: {1}", Thread.CurrentThread.Name, number);
}
}
}
}
下面我会配图进行说明,便于大家更好的理解,AutoResetEvent在使用前必须通过是例化进行初始,如:using System.Threading;
namespace AutoResetEvent_Examples
{
class MyMainClass
{
//初始的时候是没有信号的,这里的意思是指参数false
const int numIterations = 100; //重复次数设置多少都无所谓,为让大家看清楚设置了100
static AutoResetEvent myResetEvent = new AutoResetEvent(false);
static int number;
static void Main()
{
//创建并开始一个线程。
Thread myReaderThread = new Thread(new ThreadStart(MyReadThreadProc));
myReaderThread.Name = "ReaderThread";
myReaderThread.Start();
for (int i = 1; i <= numIterations; i++)
{
Console.WriteLine("Writer thread writing value: {0}", i);
number = i;
//发信号,说明值已经被写进去了。这里的意思是说Set是一个发信号的方法。
myResetEvent.Set();
//让每次循环当中有些间隔,没有其他作用,可以注释掉
Thread.Sleep(1000);
}
//终止阅读线程。
myReaderThread.Abort();
}
static void MyReadThreadProc()
{
while (true)
{
//在数据被作者写入之前不会被读者读取
//在上次读取之前至少有一次。
myResetEvent.WaitOne();
Console.WriteLine("{0} reading value: {1}", Thread.CurrentThread.Name, number);
}
}
}
}
AutoResetEvent myResetEvent = new AutoResetEvent(false);
MSDN中讲到,若要将初始状态设置为终止,则为 true;若要将初始状态设置为非终止,则为 false
小女子的理解:如过设置true,也就是说这个Event回自动Reset,那么myResetEvent.WaitOne()就能够在程序一启动就获得运行权;就相当于一启动程序就自动运行了一次myResetEven.Set();
反之,就要等myResetEven.Set()成功运行后,myResetEven.WaitOne()才能够获得运行机会;
这里我做个实验给大家看,大家会看到,在设置为true的时候会首先看到ReaderThread reading value运行,然后才是Writer thread wrirting出现:
如设置为false就会发现,先出现的是写的信息:
相信大家应该明白它的初始的意义了.
上面我们提到了myResetEven.Set(),这个方法是做什么的呢,其实简单点说就相当于一个开关,如果没有执行set()方法,下面的waitOne()就等不到让它执行的通知,这样一来waitOne后面的语句也不会执行了,waitone()就会傻等下去...一直等到set()执行后才会执行它后面的操作,
我们再次做个实验,把myResetEven.Set()注释掉,结果应该是读的信息永远不会出现,如图:
果然和我们预料的一样,只有写的信息被执行.
综合起来理解应该是这样,AutoResetEvent提供了一个类似于条件判断的开关来控制线程,
if( )
{
......
}
也就是说,如果 AutoResetEvent.Set()上面的线程完全被执行,AutoResetEvent.WaitOne()控制下的线程才被执行.很简单吧!!
也不知道小女子表达清查了没有,如果有不清楚欢迎交流!