zoukankan      html  css  js  c++  java
  • C# AutoResetEvent 使用整理

    AutoResetEvent 允许线程通过发信号互相通信。通常,此通信涉及线程需要独占访问的资源。

    线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程 通过调用 Set 发出资源可用的信号。

    调用 Set 向 AutoResetEvent 发信号以释放等待线程。AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。如果没有任何线程在等待,则状态将无限期地保持为终止状态。

    可以通过将一个布尔值传递给构造函数来控制 AutoResetEvent 的初始状态,如果初始状态为终止状态,则为 true;否则为 false。

    通俗的来讲只有等myResetEven.Set()成功运行后,myResetEven.WaitOne()才能够获得运行机会;Set是发信号,WaitOne是等待信号,只有发了信号, 等待的才会执行。如果不发的话,WaitOne后面的程序就永远不会执行。

    使用场景:需要严格按照执行顺序来执行。比如等待一个算法函数运行完出结果后,根据结果值执行下面程序。

    可以用使用myResetEven.Close()(释放由当前 WaitHandle 占用的所有资源。);释放所有的myResetEven.WaitOne()。

    如果再次使用需要myResetEvent=new AutoResetEvent(false),重新定义。

    下面例子,按照“购买饮料,投币线程,取饮料线程”顺序来执行。

    static AutoResetEvent payResetEvent = new AutoResetEvent(false);
            static AutoResetEvent getRessetEvent = new AutoResetEvent(false);
            const int times = 10;
            static int threadNumber = 0;
            private void button1_Click(object sender, EventArgs e)
            {
                Thread payThread = new Thread(new ThreadStart(PayMoney));
                payThread.Name = " 投币线程";
    
                Thread getThread = new Thread(new ThreadStart(GetDrink));
                getThread.Name = " 取饮料线程";
    
                payThread.Start();
                getThread.Start();
    
                for (int i = 1; i <= times; i++)
                {
                    threadNumber = i;
                    Console.WriteLine(" 购买饮料:编号{0}", i);
                   
                    payResetEvent.Set();
                    Thread.Sleep(1000);//加上睡眠时间让PayMoney执行完
    
                    getRessetEvent.Set();
                    Thread.Sleep(1000);
                }
    
                payThread.Abort();
                getThread.Abort();
    
            }
            static void PayMoney()
            {
                while (true)
                {
                    payResetEvent.WaitOne();
                    //myResetEvent.Reset();
                    Console.WriteLine("{0}:编号{1}", Thread.CurrentThread.Name, threadNumber);
                }
            }
            static void GetDrink()
            {
                while (true)
                {
                    getRessetEvent.WaitOne();                         
                    Console.WriteLine("{0}:编号{1}", Thread.CurrentThread.Name, threadNumber);
                    Console.WriteLine("------------------------------------------");
                    Thread.Sleep(0);
                }
            }


    执行结果:

     购买饮料:编号1
     投币线程:编号1
     取饮料线程:编号1
    ------------------------------------------
     购买饮料:编号2
     投币线程:编号2
     取饮料线程:编号2
    ------------------------------------------
     购买饮料:编号3
     投币线程:编号3
     取饮料线程:编号3
    ------------------------------------------
     购买饮料:编号4
     投币线程:编号4
     取饮料线程:编号4
    ------------------------------------------

  • 相关阅读:
    ext文件系统机制原理剖析
    win10企业版无法访问共享文件夹
    Linux 系统 CPU 的性能监控及调优
    MySQL延时复制简介
    MySQL迁移升级解决方案
    Docker 微服务教程安装WordPress
    java
    pom.xml
    sharding-jdbc
    java-MyBatis可视化代码生成工具
  • 原文地址:https://www.cnblogs.com/ike_li/p/8984186.html
Copyright © 2011-2022 走看看