暴击事件

在许多场景中,我们可能会遇到需要处理一种快速多次触发某事件,并处于某种阈值时,执行某一指定操作。例如,双击(即快速按鼠标左键两次)或更多击、连按键盘某键、某方法被执行数次等。其中,双击有对应的事件可以注册;然而,更多的情况是没有的类似事件方便我们注册使用的。那么,现在只能依靠我们勤劳的双手,来创造一个支持该功能的任务,并且该任务需要具有以下功能。

  • 可以在任务中绑定一个方法,以便在暴击后被调用。
  • 该任务可以被多次执行,包括也可以在已知事件中触发。
  • 只有当任务在短时间内执行到指定次数后,所注册的方法才会被调用。
  • 当短时间内执行了过多的次数,所注册的方法将不再被调用。
  • 短时间的界定方式是,通过指定一个连续两次任务执行间隔的最长时间,来进行控制。

那么,这该如何实现呢?

我们需要先实现一个类,这里面会提供一个方法,允许被多次调用,并返回当下是否达到暴击标准。这个方法如果在某一定义的时间范围内,被调用达到制定数量范围内,将触发这个类中的一个事件,用以通知暴击处于激活状态。这个类还需要提供一些属性,用于定义相邻两次触发过程的时间间隔最长为多少,以及暴击的最小和最大次数。当然,为了方便了解当前状况,可以提供一些属性用以获得最近一次暴击触发的时间和连续次数。因此,以下是我们定义的类。

 1 public class MultipleHitTask
 2 {
 3     public int Start
 4     { get; set; }
 5  
 6     public int End
 7     { get; set; }
 8  
 9     public TimeSpan Timeout
10     { get; private set; }
11  
12     public DateTime LatestProcess
13     { get; private set; }
14  
15     public int HitCount
16     { get; private set; }
17  
18     public event EventHandler Processed;
19  
20     public bool Process()
21     {
22         throw new NotImplementedException();
23     }
24 }

在这个类中,Processed 事件用于通知当前暴击的状况,因此我们需要对事件参数进行调整,至少让提供当前连续触发次数这一信息。

 1 /// <summary>
 2 /// The event arguments with counting.
 3 /// </summary>
 4 public class IndexEventArgs: EventArgs
 5 {
 6     /// <summary>
 7     /// Gets the index.
 8     /// </summary>
 9     public int Index { get; private set; }
10  
11     /// <summary>
12     /// Initializes a new instance
13     /// of the IndexEventArgs class.
14     /// </summary>
15     /// <param name="index">The index.</param>
16     public IndexEventArgs(int index)
17     {
18         Index = index;
19     }
20 }

于是,前面那个 MultipleHitTask 类中的 Processed 事件的声明,就应该改成下方这样。

1 public event EventHandler<IndexEventArgs> Processed;

于是,在 Process 方法中,我们需要触发该事件。

1 var args = new IndexEventArgs(HitCount - 1);
2 Processed(this, args);
3 return true;

当然,在触发事件之前,我们还要做一些判断,用以检测是否应当激活暴击状态。

 1 var now = DateTime.Now;
 2 if (LatestProcess == null || now - LatestProcess > Timeout)
 3 {
 4     HitCount = 0;
 5 }
 6  
 7 HitCount++;
 8 if (HitCount <= Start || HitCount > End)
 9 {
10     return false;
11 }

于是,我们便完成了以下代码。

 1 /// <summary>
 2 /// Multiple hit task.
 3 /// </summary>
 4 public class MultipleHitTask
 5 {
 6     /// <summary>
 7     /// Gets or sets the start index of hit to process.
 8     /// </summary>
 9     public int Start { get; set; }
10  
11     /// <summary>
12     /// Gets or sets the end index of hit to process.
13     /// </summary>
14     public int End { get; set; }
15  
16     /// <summary>
17     /// Gets the timeout.
18     /// </summary>
19     public TimeSpan Timeout { get; private set; }
20  
21     /// <summary>
22     /// Gets the time of latest processing.
23     /// </summary>
24     public DateTime LatestProcess { get; private set; }
25  
26     /// <summary>
27     /// Gets the hit count.
28     /// </summary>
29     public int HitCount { get; private set; }
30  
31     /// <summary>
32     /// Adds or removes the event handler occured
33     /// after processing
34     /// </summary>
35     public event EventHandler<IndexEventArgs> Processed;
36  
37     /// <summary>
38     /// Processes the task.
39     /// </summary>
40     /// <returns>true if match the condition to execute;
41     /// otherwise, false.</returns>
42     public bool Process()
43     {
44         var now = DateTime.Now;
45         if (LatestProcess == null
46             || now - LatestProcess > Timeout)
47         {
48             HitCount = 0;
49         }
50  
51         HitCount++;
52         if (HitCount <= Start || HitCount > End)
53             return false;
54         var args = new IndexEventArgs(HitCount - 1);
55         Processed(this, args);
56         return true;
57     }
58 }

现在,我们可以在需要的地方,初始化一个这个类的对象,并绑定暴击触发时所需执行的事件,并在诸如点击、被遥测处或其它地方,调用这个对象的 Process 方法即可。

【完】

文章类型及复杂度:C# 和 .Net 进阶。

节选翻译自 MSDN 博文 Multiple Hit Task,内容有所调整。

http://blogs.msdn.com/b/kingcean/archive/2016/03/21/multiple-hit-task.aspx

转载于:https://www.cnblogs.com/jinchen/p/multiple-hit-task.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值