新增以防抖方式执行任务。
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