using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
///
/// 这个类提供了防抖和节流的功能
///
public class DebounceDispatcher
{
System.Timers.Timer _timerDbc;
System.Timers.Timer _timerTrt;
///
/// 防抖,延迟timesMs后执行。 在此期间如果再次调用,则重新计时
///
/// 间隔(毫秒)
/// 回调函数
/// 同步对象,一般为Control控件。 如不需同步可传null
public void Debounce(int timeMs, Action action, ISynchronizeInvoke invoker = null)
{
lock (this)
{
if (_timerDbc == null)
{
_timerDbc = new System.Timers.Timer(timeMs);
_timerDbc.AutoReset = false;
_timerDbc.Elapsed += (o, e) =>
{
_timerDbc.Stop();
_timerDbc.Close();
_timerDbc = null;
InvokeAction(action, invoker);
};
}
_timerDbc.Stop();
_timerDbc.Start();
}
}
///
/// 节流,即刻执行,执行之后,在timeMs内再次调用无效
///
/// 不应期,这段时间内调用无效
/// 回调函数
/// 同步对象,一般为控件。 如不需同步可传null
public void Throttle(int timeMs, Action action, ISynchronizeInvoke invoker = null)
{
System.Threading.Monitor.Enter(this);
bool needExit = true;
try
{
if (_timerTrt == null)
{
_timerTrt = new System.Timers.Timer(timeMs);
_timerTrt.AutoReset = false;
_timerTrt.Elapsed += (o, e) =>
{
_timerTrt.Stop();
_timerTrt.Close();
_timerTrt = null;
};
_timerTrt.Start();
System.Threading.Monitor.Exit(this);
needExit = false;
InvokeAction(action, invoker);//这个过程不能锁
}
}
finally
{
if (needExit)
System.Threading.Monitor.Exit(this);
}
}
private static void InvokeAction(Action action, ISynchronizeInvoke invoker)
{
if (invoker == null)
{
action();
}
else
{
if (invoker.InvokeRequired)
{
invoker.Invoke(action, null);
}
else
{
action();
}
}
}
}