AutoResetEvent与ManualResetEvent区别

【转载】AutoResetEvent与ManualResetEvent区别

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.....”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值