ManualResetEvent 和 AutoResetEvent,它们的区别

上一篇 / 下一篇  2010-02-03 22:14:15 / 个人分类:c#测试

ManualResetEvent 和 AutoResetEvent

从字面意思看,它们都表示是一个事件(Event)。这两个类都有WaitOne方法,这个方法被调用后,当前的线程(即是调用这个方法的线程)暂停运行(可以看做等待事件触发),直到事件被触发(即另外的线程调用了它的Set方法)

ManualReset说明这个事件被触发后(Set方法被调用),是要手工进行重置的(即调用Reset方法),否则再次调用它的WaitOne方法是没有用的(也就是调用WaitOne的线程不会停下等待事件触发,而是继续执行)。 它提供手工重置的方法是调用Reset方法。

AutoResetEvent则是Set被调用后,如果WaitOne再次被调用,当前的线程还是会被暂停的,也就是不用手工调用它的Reset方法,就能使WaitOne再次生效。

看下面几个示例

namespace Demo
{
    [TestClass]
    public class ThreadDemo
    {

        [TestMethod]
        public void ThreadTest()
        {
            Thread thread1 = new Thread(new ThreadStart(Print));
            thread1.Start();
        }

        public void Print()
        {
            Thread.Sleep(1000);
            Console.WriteLine("Print.....");
        }

}

上面这个示例的输出为空。因为thread1.Start()后,线程继续运行结束。而Print()方法中因为有Thread.Sleep(1000),所以Console.WriteLine("Print.....");还没来得及运行,主线程就结束了。

怎么让主线程等待呢。可以通过ManualResetEvent 或 AutoResetEvent的WaitOne()方法。见下面的示例

namespace Demo
{
    [TestClass]
    public class ThreadDemo
    {
        private ManualResetEvent manualResetEvent;

        [TestMethod]
        public void ThreadTest()
        {
            manualResetEvent = new ManualResetEvent(false);
            Thread thread1 = new Thread(new ThreadStart(Print));
            thread1.Start();
            manualResetEvent.WaitOne();
        }

        public void Print()
        {
            Thread.Sleep(1000);
            Console.WriteLine("Print.....");
            manualResetEvent.Set();
        }

上面的示例输出为: "Print.....". 因为主线程中调用了manualResetEvent.WaitOne(),它一定要等到Print()方法中的manualResetEvent.Set()执行完后才能继续往下进行。

将ManualResetEvent 换成AutoResetEvent也能达到上面一样的效果,见下例。

namespace Demo
{
    [TestClass]
    public class ThreadDemo
    {
        private AutoResetEvent autoResetEvent;

        [TestMethod]
        public void ThreadTest()
        {
            autoResetEvent = new AutoResetEvent(false);
            Thread thread1 = new Thread(new ThreadStart(Print));
            thread1.Start();
            autoResetEvent.WaitOne();
        }

        public void Print()
        {
            Thread.Sleep(1000);
            Console.WriteLine("Print.....");
            autoResetEvent.Set();
        }

输出也是: "Print....."。

下面的示例演示AutoResetEvent调用过Set方法后,再次调用WaitOne还是有用的

namespace Demo
{
    [TestClass]
    public class ThreadDemo
    {
        private AutoResetEvent autoResetEvent;

        [TestMethod]
        public void ThreadTest()
        {
            autoResetEvent = new AutoResetEvent(false);
            Thread thread1 = new Thread(new ThreadStart(Print));
            thread1.Start();
            autoResetEvent.WaitOne();
            thread1 = new Thread(new ThreadStart(Print));
            thread1.Start();
            autoResetEvent.WaitOne();
        }

        public void Print()
        {
            Thread.Sleep(1000);
            Console.WriteLine("Print.....");
            autoResetEvent.Set();
        }

输出为:

Print.....
Print.....

 

而下面的示例演示ManualResetEvent调用过Set方法后,再次调用WaitOne是无效的,必须先调用Reset方法

namespace Demo
{
    [TestClass]
    public class ThreadDemo
    {
        private ManualResetEvent manualResetEvent;

        [TestMethod]
        public void ThreadTest()
        {
            manualResetEvent = new ManualResetEvent(false);
            Thread thread1 = new Thread(new ThreadStart(Print));
            thread1.Start();
            manualResetEvent.WaitOne();
            thread1 = new Thread(new ThreadStart(Print));
            thread1.Start();
            manualResetEvent.WaitOne();
        }

        public void Print()
        {
            Thread.Sleep(1000);
            Console.WriteLine("Print.....");
            manualResetEvent.Set();
        }

输出为: “Print.....”。

 


TAG:

 

评分:0

我来说两句

日历

« 2024-05-16  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 6257
  • 日志数: 10
  • 文件数: 2
  • 建立时间: 2010-01-29
  • 更新时间: 2010-02-10

RSS订阅

Open Toolbar