You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何取消前置异步任务,仅保留最后一次执行结果更新UI?

解决异步任务重复调用导致UI闪烁的问题

这个场景在高频触发的异步操作里特别常见,核心思路就是取消或忽略之前未完成的异步任务,只让最后一次调用的结果更新UI。我们可以借助CancellationTokenSource来实现这个需求,具体方案如下:

1. 新增取消令牌源字段

在你的类中添加一个私有字段,用来跟踪当前正在执行的异步任务的取消令牌:

private CancellationTokenSource _currentDescriptionCts;

2. 修改DisplayShortDescription方法

每次调用方法时,先取消之前未完成的任务,再创建新的令牌,最后在异步操作完成后判断是否要执行UI更新:

private async void DisplayShortDescription(object parameter) {
    var targetId = (int)parameter;

    // 取消之前未完成的任务
    _currentDescriptionCts?.Cancel();
    
    // 创建新的取消令牌源,用using确保资源被正确释放
    using var newCts = new CancellationTokenSource();
    _currentDescriptionCts = newCts;

    try {
        // 如果你的FindDescription方法支持取消,建议传入令牌终止不必要的操作
        var description = await FindDescription(targetId, newCts.Token);

        // 只有当前令牌未被取消(说明这是最后一次调用),才更新UI
        if (!newCts.IsCancellationRequested) {
            ShortDescription = description.ShortDescription;
            CurrentDescriptionId = targetId;
        }
    } catch (OperationCanceledException) {
        // 任务被取消,无需做额外处理
    }
}

3. 适配FindDescription方法(可选但推荐)

如果FindDescription是IO密集型操作(比如调用API、查询数据库),建议让它接受CancellationToken参数,这样能真正取消正在执行的异步操作,避免浪费资源:

private async Task<DescriptionModel> FindDescription(int id, CancellationToken token) {
    // 示例:调用API时传入令牌
    using var httpClient = new HttpClient();
    var response = await httpClient.GetAsync($"https://your-api/descriptions/{id}", token);
    return await response.Content.ReadFromJsonAsync<DescriptionModel>(token);
}

原理说明

  • 每次触发DisplayShortDescription时,先取消之前的CancellationTokenSource,这样之前的任务要么被直接终止(如果支持取消),要么在完成后检查到IsCancellationRequested为true,跳过UI更新。
  • 最后一次调用的任务不会被后续调用取消,所以它的IsCancellationRequested会保持false,最终执行UI更新代码。

内容的提问来源于stack exchange,提问作者Nikita Goncharuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:12:57