使用 CancellationTokenSource 实现防抖

private CancellationTokenSource _debounceCts;
private const int DebounceDelay = 500; // 毫秒

// 拖拽事件中调用
public void OnTimelineDrag(object newTime)
{
  // 每次拖拽都取消上一个任务
  _debounceCts?.Cancel();
  _debounceCts = new CancellationTokenSource();
  var token = _debounceCts.Token;

  // 启动一个延迟任务,如果中途被取消就不会执行查询
  _ = DebounceQueryAsync(newTime, token);
}

private async Task DebounceQueryAsync(object newTime, CancellationToken token)
{
  try
  {
    await Task.Delay(DebounceDelay, token); // 延迟 0.5 秒,如果期间有新操作就取消

    // token 没被取消,说明用户停止拖拽了
    QueryDataAndRenderUI(newTime);
  }
  catch (TaskCanceledException)
  {
    // 被取消,无需操作
  }
}

private void QueryDataAndRenderUI(object time)
{
  // 查询数据
  var data = QueryData(time);

  // 渲染 UI(在 UI 线程中执行,如果需要)
  Application.Current.Dispatcher.Invoke(() =>
  {
    RenderUI(data);
  });
}
🔍 说明

  • 每次拖拽操作会取消上一次的任务。

  • 如果用户停下来 0.5 秒没再操作,就执行查询和 UI 更新。

  • 不用 Timer,全部用 async/awaitCancellationToken 实现,非常适合现代 C# 应用(WPF / WinForms / MAUI / etc.)。


✅ 优点

  • 避免了频繁调用查询逻辑。

  • 没有 Timer,也没有额外线程。

  • 可读性和控制力强。

  • 可以集成到 ViewModel 或组件中。

posted @ 2025-06-27 10:49  MaxBruce  阅读(37)  评论(0)    收藏  举报