zoukankan      html  css  js  c++  java
  • 16订阅者方法超时的处理

    订阅者方法超时会让客户端程序出现某种程度的中断。
    模拟考试,比较现实的状况是谁先答完,谁先交试卷,不可能按学生序号来决定交试卷顺序。

      先模拟一个订阅者方法超时

    □ 老师的职责是组织考试,并让每个注册学生(订阅者)答题。

       1:      public class Teacher
       2:      {
       3:          public event EventHandler TestEvent;
       4:   
       5:          public void Test()
       6:          {
       7:              Console.WriteLine("老师:同学们,现在开始考试");
       8:   
       9:              //触发事件的所有注册方法
      10:              //实际上也有返回值的,只不过没有获取
      11:              //第二个参数是被监视对象,相当于object sender
      12:              EventHelper.FireEvent(TestEvent, this, EventArgs.Empty);
      13:          }
      14:      }


    □ EventHelper是关于触发注册方法的静态类。主要是遍历委托链表,让链表上的每个方法得以执行

    3

    □ 学生的职责是考试,答题速度有快有慢

       1:      public class Student1
       2:      {
       3:          public void DoTest(Object sender, EventArgs e)
       4:          {
       5:              Thread.Sleep(TimeSpan.FromSeconds(3));
       6:              Console.WriteLine("Student1用了3秒钟答题交试卷了");
       7:          }
       8:      }
       9:   
      10:      public class Student2
      11:      {
      12:          public void DoTest(Object sender, EventArgs e)
      13:          {
      14:              Thread.Sleep(TimeSpan.FromSeconds(2));
      15:              Console.WriteLine("Student2用了2秒钟答题交试卷了");
      16:          }
      17:      }
      18:   
      19:      public class Student3
      20:      {
      21:          public void DoTest(Object sender, EventArgs e)
      22:          {
      23:              Thread.Sleep(TimeSpan.FromSeconds(1));
      24:              Console.WriteLine("Student3用了1秒钟答题交试卷了");
      25:          }
      26:      }

    □ 主程序注册方法,老师触发宣布考试开始

       1:      class Program
       2:      {
       3:          static void Main(string[] args)
       4:          {
       5:              Teacher teacher = new Teacher();
       6:              Student1 student1 = new Student1();
       7:              Student2 student2 = new Student2();
       8:              Student3 student3 = new Student3();
       9:   
      10:              teacher.TestEvent += new EventHandler(student1.DoTest);
      11:              teacher.TestEvent += new EventHandler(student2.DoTest);
      12:              teacher.TestEvent += new EventHandler(student3.DoTest);
      13:   
      14:              
      15:              teacher.Test();
      16:              Console.WriteLine("老师:考试结束");
      17:              Console.ReadKey();
      18:          }
      19:      }   

    □ 结果        

    1

    □ 可见

    不管学生的答题速度如何,都是按学生编号顺序交试卷,显然不合理。

      使用EventHandler的BeginInvoke()方式实现异步执行订阅者方法

    修改老师的类,让老师用异步方法来触发订阅者方法。

       1:      public class Teacher
       2:      {
       3:          public event EventHandler TestEvent;
       4:   
       5:          public void Test()
       6:          {
       7:              Console.WriteLine("老师:同学们,现在开始考试");
       8:   
       9:              if (TestEvent != null)
      10:              {
      11:                  Delegate[] delArray = TestEvent.GetInvocationList(); //获取事件的委托链表
      12:                  foreach (Delegate del in delArray)
      13:                  {
      14:                      EventHandler method = (EventHandler)del;
      15:                      method.BeginInvoke(null, EventArgs.Empty, null, null);
      16:                  }
      17:              }
      18:          }
      19:      }

    结果:
    2

    可见:
    ● 当异步执行订阅者方法的时候,客户端程序不会等到所有订阅者方法执行完成才进行,而是不理会订阅者的异步方法执行结果。
    ● 当异步执行订阅者方法的时候,最先执行完的先返回结果。
    ● BeginInvoke()是事件的方法,不是Delegate的方法,只能把委托链表中的委托向下转换成事件,再让事件执行异步方法。

  • 相关阅读:
    字符串题表
    插头dp题表
    点分治题表
    Kd-tree题表
    【BZOJ 4605】崂山白花蛇草水 替罪羊树套线段树
    假的kd-tree小结
    【BZOJ 1492】 [NOI2007]货币兑换Cash 斜率优化DP
    CDQZ 2017 游记
    【BZOJ 1146】[CTSC2008]网络管理Network
    联赛之前的题表(已完成)汇总(可能有遗漏)
  • 原文地址:https://www.cnblogs.com/darrenji/p/3618547.html
Copyright © 2011-2022 走看看