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

Xamarin中自动补全的API调用延迟与请求取消实现问题

Xamarin自动补全延迟触发+请求取消解决方案

要实现你需要的“等待用户输入完成后再触发API”的逻辑,CancellationTokenSource是核心工具,配合Task.Delay完全能满足需求。你的问题根源在于没对之前的延迟任务和API请求做取消处理,下面是具体实现方案:

核心思路

  • 用类级别的CancellationTokenSource跟踪当前待执行的延迟任务与API请求
  • 每次文本变化时,先取消所有未完成的旧任务(不管是延迟等待还是正在跑的API)
  • 创建新的令牌源,等待300ms后再发起API请求
  • API请求方法也要兼容取消令牌,确保中途能终止无效请求

修改后的完整代码

// 类级别字段:跟踪当前搜索任务的取消令牌源
private CancellationTokenSource _searchCts;

private async void TextChangedEvent(System.Object sender, ItemsChangedEventArgs e)
{
    var autoComplete = sender as AutoComplete;
    if (autoComplete == null) return;
    
    var searchText = autoComplete.Text.Trim();
    // 搜索文本为空时,直接清空补全列表并返回
    if (string.IsNullOrEmpty(searchText))
    {
        // 这里添加清空自动补全列表的逻辑,比如:autoComplete.ItemsSource = null;
        return;
    }

    // 取消之前未完成的任务(延迟或API请求)
    _searchCts?.Cancel();
    // 释放旧令牌源资源
    _searchCts?.Dispose();

    // 创建新的令牌源,用于本次搜索
    _searchCts = new CancellationTokenSource();
    try
    {
        // 等待300ms,期间有新输入会触发取消
        await Task.Delay(TimeSpan.FromMilliseconds(300), _searchCts.Token);
        
        // 300ms内无新输入,发起API请求
        var results = await GetStatus(searchText, _searchCts.Token);
        
        // 将结果绑定到自动补全控件,示例:autoComplete.ItemsSource = results;
    }
    catch (OperationCanceledException)
    {
        // 任务被取消,无需处理,直接忽略
    }
    finally
    {
        // 释放当前令牌源,避免内存泄漏
        _searchCts?.Dispose();
        _searchCts = null;
    }
}

// 修改GetStatus方法,添加CancellationToken参数支持取消
private async Task<List<string>> GetStatus(string searchText, CancellationToken cancellationToken)
{
    // 替换为你的实际API请求逻辑
    using var httpClient = new HttpClient();
    // 传入取消令牌,确保请求中途可终止
    var response = await httpClient.GetAsync($"your-api-endpoint?keyword={searchText}", cancellationToken);
    
    response.EnsureSuccessStatusCode();
    var content = await response.Content.ReadAsStringAsync(cancellationToken);
    
    // 解析返回内容,替换为你需要的实体类型
    return JsonConvert.DeserializeObject<List<string>>(content);
}

关键细节说明

  • _searchCts?.Cancel():每次新输入触发时,立刻终止之前的延迟任务和API请求,确保只有最后一次输入对应的请求会执行
  • Task.Delay(300, _searchCts.Token):延迟过程中如果令牌被取消,会直接抛出OperationCanceledException,进入catch块忽略即可
  • API请求传入cancellationToken:即使延迟已完成、API请求已发起,新输入仍能终止正在进行的HTTP请求,避免无效响应占用资源
  • finally块释放资源:确保每次操作后令牌源被正确清理,防止内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 14:40:49