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
相关产品推荐
相关产品推荐

