C# ManualResetEvent使用测试

来源:互联网 发布:mac ie浏览器 编辑:程序博客网 时间:2024/05/25 05:38

一直对ManualResetEvent的用法不是很明白,今天决定写些小程序,测试一下,直观感受它的用法。

MSDN的解释: 通知一个或多个正在等待的线程已发生事件。 此类不能被继承。

Part1:初始化

        // 初始化一个ManualResetEvent实例        private static ManualResetEvent _mer = new ManualResetEvent(false);
可见,初始化时接受一个bool值,它是有什么作用呢?

MSND的解释:用一个指示是否将初始状态设置为终止的布尔值初始化 ManualResetEvent类的新实例。即:可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false

用程序来直观感受一下:

static void Main(string[] args)        {            Console.WriteLine("Enter Main" + Thread.CurrentThread.Name);            for (int id = 0; id < 2; id++)            {                Thread th = new Thread(new ThreadStart(ThreadProc));                th.Name = "thread_" + id.ToString();                th.Start();            }        }
private static void ThreadProc()        {            Console.WriteLine("Enter ThreadProc" + Thread.CurrentThread.Name);            Console.WriteLine("before WaitOne " + Thread.CurrentThread.Name);            _mer.WaitOne();            Console.WriteLine("after WaitOne " + Thread.CurrentThread.Name);            Console.WriteLine("Exit ThreadProc" + Thread.CurrentThread.Name);        }

测试结果:



先加个解释,ThreadProc里用到了WaitOne(), MSDN的解释是:阻止当前线程,直到当前 WaitHandle 收到信号。 (继承自WaitHandle。)

回到初始化,初始化为false,即_mer是非终止状态,这里我想加个自己的理解,非终止状态就是工作状态,就是说_mer是起作用的,从程序的结果可以看到,

程序停在了_mer.WaitOne(); 这一句,没有输出Console.WriteLine("after WaitOne " + Thread.CurrentThread.Name);这句,就是说_mer起作用了。

如果初始化时是true,即终止状态,就是非工作状态,程序执行的结果就是执行完毕,闪退。

总结: 初始化为true,终止状态,即不起作用状态;初始化为false,非终止状态,即起作用状态。


Part2:Set与Reset

ManualResetEvent.Set()   MSDN的解释:将事件状态设置为终止状态,允许一个或多个等待线程继续。 (继承自EventWaitHandle。)

也就是将ManualResetEvent实例设置为不起作用状态。

程序测试:

_mer初始化还是false,Main() 方法里加了一句: _mer.Set();

        static void Main(string[] args)        {            Console.WriteLine("Enter Main" + Thread.CurrentThread.Name);            _mer.Set();            for (int id = 0; id < 2; id++)            {                Thread th = new Thread(new ThreadStart(ThreadProc));                th.Name = "thread_" + id.ToString();                th.Start();            }        }
执行结果:执行完毕,闪退。即: _mer.WaitOne(); 不起作用。


ManualResetEvent.Reset()  MSDN解释:将事件状态设置为非终止状态,导致线程阻止。

即设置为起作用状态。

程序测试:

初始化一个为true的实例,Main()方法里加了一句:_mer.Reset();

static void Main(string[] args)        {            Console.WriteLine("Enter Main" + Thread.CurrentThread.Name);            _mer.Reset();            for (int id = 0; id < 2; id++)            {                Thread th = new Thread(new ThreadStart(ThreadProc));                th.Name = "thread_" + id.ToString();                th.Start();            }        }

执行结果:


可见, 初始化为true,终止状态(不起作用状态),Reset()后,就为非终止状态(起作用状态)。


Part3 : WaitOne(Int32)

 MSDN的解释:阻止当前线程,直到当前 WaitHandle 收到信号,同时使用 32 位带符号整数指定时间间隔(以毫秒为单位)
   

     private static void ThreadProc()        {            Console.WriteLine("Enter ThreadProc" + Thread.CurrentThread.Name);            Console.WriteLine("before WaitOne " + Thread.CurrentThread.Name);            _mer.WaitOne(5000);            Console.WriteLine("after WaitOne " + Thread.CurrentThread.Name);            Console.WriteLine("Exit ThreadProc" + Thread.CurrentThread.Name);            Console.Read();        }
程序中有一句:
 _mer.WaitOne(5000);
阻塞5秒钟,程序执行完毕。
如果在Main方法里加上这两句:
            Thread.Sleep(2000);            _mer.Set();
<pre name="code" class="csharp">static void Main(string[] args)        {            Console.WriteLine("Enter Main" + Thread.CurrentThread.Name);            for (int id = 0; id < 2; id++)            {                Thread th = new Thread(new ThreadStart(ThreadProc));                th.Name = "thread_" + id.ToString();                th.Start();            }            Thread.Sleep(2000);            _mer.Set();        }
程序执行情况是: ThreadProc阻塞,2秒钟接收到Set()信号, 执行WaitOne(5000)后面的语句,即只阻塞了两秒。
今天是对ManualResetEvent的几个方法有了直观的了解, 接下来有时间再测试他们在线程同步中的使用。

0 0
原创粉丝点击