RateLimitedWorker.cs 1.4 KB

1234567891011121314151617181920212223242526272829303132333435
  1. namespace MeloongCore;
  2. public enum RateLimitMode {
  3. /// <summary>Throttle:立即执行一次,然后一段时间内合并为一次尾随执行。</summary>
  4. ImmediateThenMerge,
  5. /// <summary>Debounce (leading):立即执行一次,然后忽略一段时间内的后续调用。</summary>
  6. ImmediateThenIgnore,
  7. /// <summary>Debounce (trailing):不立即执行,直到一段时间内不再有任何新调用后再执行一次。</summary>
  8. WaitUnillNoNewInvoke,
  9. }
  10. /// <summary>
  11. /// 对高频调用进行限制。
  12. /// 详见:<see href="https://aldaviva.com/portfolio.html#ratelimiting" />
  13. /// </summary>
  14. public class RateLimitedWorker(Action workload, double minimalIntervalMs, RateLimitMode mode) : IDisposable {
  15. private readonly RateLimitedAction action = mode switch {
  16. RateLimitMode.ImmediateThenMerge => Throttler.Throttle(workload, TimeSpan.FromMilliseconds(minimalIntervalMs), leading: true, trailing: true),
  17. RateLimitMode.WaitUnillNoNewInvoke => Debouncer.Debounce(workload, TimeSpan.FromMilliseconds(minimalIntervalMs), leading: false, trailing: true),
  18. _ => Debouncer.Debounce(workload, TimeSpan.FromMilliseconds(minimalIntervalMs), leading: true, trailing: false)
  19. };
  20. public void Start() {
  21. if (!disposed) action.Invoke();
  22. }
  23. private bool disposed = false;
  24. public virtual void Dispose() {
  25. if (disposed) return;
  26. disposed = true;
  27. action.Dispose();
  28. }
  29. }