C#中多线程ManualResetEvent 与 AutoResetEvent 区别

 更新时间:2020年07月16日 15:15:57   作者:千浔  
这篇文章主要介绍了C#中ManualResetEvent 与 AutoResetEvent 区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在多线程开发中,时常用到ManualResetEvent 与AutoResetEvent 。 它们如同道路交通中的信号灯。两者之间有什么区别呢?

共同点:

均继承EventWaitHandle 接口,因此,均具有以下功能:
Reset() //红灯
Set() //绿灯
WaitOne() // 等待信号

不同点:

AutoResetEvent 收到 Set 后 , 一次只能执行一个线程,其它线程继续 WaitOne 。
ManualResetEvent 收到 Set 后,所有处理 WaitOne 状态线程均继续执行。

msdn 提到(如果没有线程 处于WaitOne() 状态,而调用 Set ,AutoResetEvent将保持Set 状态):

调用Set信号AutoResetEvent释放等待线程。 AutoResetEvent 将保持终止状态直到一个等待线程释放,并自动返回到非信号状态。 如果没有线程处于等待状态,状态将无限期地保持已发出信号。

因此通常WatiOne 之前,先 Reset() 一下,清除Set 信号

需要注意的是(两个 Set 调用之间时间较短,第二个 Set 信号可能会丢失,因此连续 Set 调用,中间需要 Sleep 一定时间):

不能保证的每个调用Set方法将释放一个线程。 如果两次调用太靠近在一起,以便第二次调用前释放线程发生,只有一个线程被释放。 就像第二次调用未发生。 此外,如果Set时没有等待的线程调用和AutoResetEvent已终止,则调用不起作用。

有网友说:

AutoResetEvent.Set() = ManualResetEvent.Set() + ManualResetEvent.Reset();

个人理解 ,这只是原理层面含义,实际使用过程中,有差别的,如下示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace testManualResetEvent
{
  class Program
  {
    static object objManualResetEvent = new object();
    static System.Threading.ManualResetEvent manu = new System.Threading.ManualResetEvent(false);
     //static System.Threading.AutoResetEvent manu = new System.Threading.AutoResetEvent(false);
    static void Main(string[] args)
    {
      
      for (int i = 0; i < 10; i++)
      {
        System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() => { Product(); }));
        t.Start();
      }
      
      manu.Set();
      manu.Reset();

      Console.ReadKey();
    }

    static void Product()
    {
      manu.WaitOne(10000);
      Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
    }
  }
}

实际执行结果 , 在 执行 set 后 reset 前 ,有多少个线程唤起执行,无法预料:

需要加锁 ,确保一次通过一个线程:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace testManualResetEvent
{
  class Program
  {
    static object objManualResetEvent = new object();
    static System.Threading.ManualResetEvent manu = new System.Threading.ManualResetEvent(false);
     //static System.Threading.AutoResetEvent manu = new System.Threading.AutoResetEvent(false);
    static void Main(string[] args)
    {
      
      for (int i = 0; i < 10; i++)
      {
        System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() => { Product(); }));
        t.Start();
      }
      
      manu.Set();

      //System.Threading.Thread.Sleep(100); //连续 set 需要 sleep
      //manu.Set();
      //manu.Reset();

      //System.Threading.Thread.Sleep(100);
      //manu.Set();
      //manu.Reset();

      Console.ReadKey();
    }

    static void Product()
    {
      lock (objManualResetEvent)
      {
        manu.WaitOne(10000);          manu.Reset();
        Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
      }
    }
  }
}

执行结果:

到此这篇关于C#中ManualResetEvent 与 AutoResetEvent 区别的文章就介绍到这了,更多相关C#中ManualResetEvent  AutoResetEvent 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#操作Access数据库的实现过程(vs2019)

    C#操作Access数据库的实现过程(vs2019)

    这篇文章主要介绍了C#操作Access数据库的实现过程(vs2019),打开Office Access新建一个空白数据库DATA.accdb,并改好存放位置,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-02-02
  • C#通过yield实现数组全排列的方法

    C#通过yield实现数组全排列的方法

    这篇文章主要介绍了C#通过yield实现数组全排列的方法,以实例形式较为详细的分析了全排列的概念及C#的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • C#导入导出EXCEL文件的代码实例

    C#导入导出EXCEL文件的代码实例

    这篇文章主要介绍了C#导入导出EXCEL文件代码实例,代码的流程和方法都很详细,需要的朋友可以参考下
    2014-04-04
  • c#使用listbox的详细方法和常见问题解决

    c#使用listbox的详细方法和常见问题解决

    这篇文章介绍了c#使用listbox的详细方法和常见问题解决,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • C#设计模式之简单工厂模式

    C#设计模式之简单工厂模式

    这篇文章介绍了C#设计模式之简单工厂模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • c#隐藏基类方法的作用

    c#隐藏基类方法的作用

    这篇文章主要介绍了c#隐藏基类方法的作用,大家可以参考使用
    2013-12-12
  • C# Timer控件学习之使用Timer解决按钮幂等性问题

    C# Timer控件学习之使用Timer解决按钮幂等性问题

    Timer控件又称定时器控件或计时器控件,该控件的主要作用是按一定的时间间隔周期性地触发一个名为Tick的事件,因此在该事件的代码中可以放置一些需要每隔一段时间重复执行的程序段,这篇文章主要介绍了关于C#使用Timer解决按钮幂等性问题的相关资料,需要的朋友可以参考下
    2022-10-10
  • 深入分析C#中的异步和多线程

    深入分析C#中的异步和多线程

    这篇文章主要介绍了C#中异步和多线程的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下
    2021-01-01
  • unity scrollRect实现按页码翻页效果

    unity scrollRect实现按页码翻页效果

    这篇文章主要为大家详细介绍了unity scrollRect实现按页码翻页效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C#中各种类型集合的特点详解

    C#中各种类型集合的特点详解

    这篇文章主要介绍了概述C#中各种类型集合的特点,这些集合通常位于 System.Collections 和 System.Collections.Generic 命名空间中,下面我将概述C#中几种常用的集合类型及其特点,需要的朋友可以参考下
    2024-08-08

最新评论