新增以防抖方式执行任务。
This commit is contained in:
parent
416b0cd37a
commit
e62db70d44
42
Falcon.SugarApi.Test/ShakingTests.cs
Normal file
42
Falcon.SugarApi.Test/ShakingTests.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Falcon.SugarApi.Test
|
||||
{
|
||||
/// <summary>
|
||||
/// 任务防抖测试
|
||||
/// </summary>
|
||||
[TestClass()]
|
||||
public class ShakingTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 任务防抖测试
|
||||
/// </summary>
|
||||
[TestMethod()]
|
||||
public void RunTest() {
|
||||
var showMsg = () => Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")} show message!");
|
||||
|
||||
var reMsg = () => $"{DateTime.Now.ToString("HH:mm:ss")} show message!";
|
||||
|
||||
var task = new Task<string>(reMsg);
|
||||
int span = 5;
|
||||
var shaking = new Shaking(span);
|
||||
|
||||
//showMsg();
|
||||
//await Task.Delay(5 * 1000);
|
||||
//shaking.Run(showMsg);
|
||||
Console.WriteLine($"以下方法调用3次,应该有两个输出,相隔{span}秒");
|
||||
Console.WriteLine(reMsg());
|
||||
shaking.Run(task);
|
||||
task = new Task<string>(reMsg);
|
||||
shaking.Run(task);
|
||||
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss")} {span}秒后记录第二个输出");
|
||||
Console.WriteLine(task.Result);
|
||||
Console.WriteLine("任务完成!");
|
||||
}
|
||||
}
|
||||
}
|
109
Falcon.SugarApi/Shaking.cs
Normal file
109
Falcon.SugarApi/Shaking.cs
Normal file
|
@ -0,0 +1,109 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Falcon.SugarApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 防止抖动执行任务
|
||||
/// <para>每个任务加入后都会等待一段时间后开始执行。如果在等待期间有新的任务加入,旧任务会被放弃并重新记录等待时间。</para>
|
||||
/// <para>用这种方式可以防止同样的类似任务被频繁触发,
|
||||
/// 比如用户连续快速点击按钮导致点击事件处理程序多次执行,用此类可以保证只执行一次。</para>
|
||||
/// <para>但是也产生了一些副作用,第一是不管怎么样方法总是会等待一定时间后延迟触发。
|
||||
/// 还有一个副作用,因为后加入的任务会导致先加入的未执行的任务被放弃,所以如果所有任务都必须执行,那就不要使用此类了。</para>
|
||||
/// </summary>
|
||||
public class Shaking:IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 下一个要执行的任务
|
||||
/// </summary>
|
||||
protected Task? Next { get; set; }
|
||||
/// <summary>
|
||||
/// 执行计时器
|
||||
/// </summary>
|
||||
protected System.Timers.Timer Timer { get; set; }
|
||||
/// <summary>
|
||||
/// 等待执行时间
|
||||
/// </summary>
|
||||
public int TimespanSeconds { get; set; }
|
||||
/// <summary>
|
||||
/// 使用默认方式实例化
|
||||
/// </summary>
|
||||
public Shaking() : this(5) { }
|
||||
/// <summary>
|
||||
/// 实例化,默认抖动执行间隔5秒
|
||||
/// </summary>
|
||||
/// <param name="timeSpanSeconds">抖动执行时间间隔。秒</param>
|
||||
public Shaking(int timeSpanSeconds) {
|
||||
this.TimespanSeconds = timeSpanSeconds * 1000;
|
||||
this.Timer = new System.Timers.Timer {
|
||||
Interval = this.TimespanSeconds
|
||||
};
|
||||
this.Timer.Elapsed += TimerTick;
|
||||
this.Timer.Stop();
|
||||
}
|
||||
/// <summary>
|
||||
/// 时间到达,执行任务
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
protected void TimerTick(object? sender,EventArgs e) {
|
||||
this.Timer.Stop();
|
||||
this.Timer.Dispose();
|
||||
if(this.Next == null) {
|
||||
return;
|
||||
}
|
||||
var n = this.Next;
|
||||
this.Next = null;
|
||||
n.Start();
|
||||
}
|
||||
/// <summary>
|
||||
/// 新增任务
|
||||
/// <para>未执行任务将会放弃</para>
|
||||
/// </summary>
|
||||
/// <param name="task">要执行的任务</param>
|
||||
public void Run(Task task) {
|
||||
this.Next = task;
|
||||
if(this.Timer != null) {
|
||||
this.Timer.Stop();
|
||||
this.Timer.Dispose();
|
||||
}
|
||||
this.Timer = new System.Timers.Timer {
|
||||
Interval = this.TimespanSeconds,
|
||||
};
|
||||
this.Timer.Elapsed += TimerTick;
|
||||
this.Timer.Start();
|
||||
}
|
||||
/// <summary>
|
||||
/// 新增任务委托
|
||||
/// <para>未执行任务将会放弃</para>
|
||||
/// </summary>
|
||||
/// <param name="action">要执行的委托</param>
|
||||
public void Run(Action action) => Run(new Task(action));
|
||||
/// <summary>
|
||||
/// 释放资源,未执行的任务放弃
|
||||
/// </summary>
|
||||
public void Dispose() {
|
||||
if(this.Timer != null) {
|
||||
this.Timer.Stop();
|
||||
this.Timer.Dispose();
|
||||
}
|
||||
this.Next = null;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
/// <summary>
|
||||
/// 立即执行任务
|
||||
/// </summary>
|
||||
public void RunNow() {
|
||||
var n = this.Next;
|
||||
this.Next = null;
|
||||
if(n == null) {
|
||||
return;
|
||||
}
|
||||
if(this.Timer != null) {
|
||||
this.Timer.Stop();
|
||||
this.Timer.Dispose();
|
||||
}
|
||||
n.Start();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user