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

Xamarin Forms中Azure搜索API输入延迟搜索优化求助

实现输入停顿后触发Azure搜索API的优化方案

我在学习Xamarin Forms,用Azure搜索API查询新闻,但现有搜索逻辑有问题,输入关键词时经常因为延迟导致发送不完整的内容给API,比如输入“cat”时实际发送的是“ca”。

期望实现用户停止输入时自动触发搜索:比如输入“tennis is a sport”,输入“tennis is”后停顿就触发该关键词搜索;整句输入完成停顿后,再触发完整关键词的搜索,也接受更优实现方案。

最初尝试的代码

Task tasksearch = null;
int timeDelaySearch = 1000;

void OnSearcMyNews(System.Object sender, Xamarin.Forms.TextChangedEventArgs e)
{
    try {
        if (tasksearch == null || tasksearch.IsCompleted)
        {
            tasksearch = Task.Run(async () =>
                {
                    await Task.Delay(timeDelaySearch);

                    Device.BeginInvokeOnMainThread( () =>
                    {
                        searchTerm = searchTerm.ToLower();
                        _ = SearchNewsDataAsync(searchTerm, UserConnected.NewsLanguage);
                        tasksearch = null;
                    });
            });
        }
    }
    catch (Exception ex)
    {
    }
}

2月26日更新的尝试代码

int _countSeconds = 0;
void OnSearcMyNews(System.Object sender, Xamarin.Forms.TextChangedEventArgs e)
{
    try {
        _countSeconds = 0; // 用户再次输入时重置计数
        Device.StartTimer(TimeSpan.FromMilliseconds(1000), () =>
        {
            // 计数到2时触发搜索
            if (_countSeconds == 2)
            {
                _ = Task.Run(async () => {
                    await Device.InvokeOnMainThreadAsync(async () =>
                    {
                         GetNewsAPIDataAsync();
                    });
                });
                return false;
            }
            _countSeconds = _countSeconds + 1;
            return true;
        });
    }
    catch (Exception ex)
    {
    }
}

优化实现方案

核心问题是未正确取消之前的延迟任务,导致用户连续输入时旧任务仍会触发搜索。以下是可靠的实现方式:

方案思路

  • 维护CancellationTokenSource对象,每次用户输入时取消之前的延迟任务
  • 设置合理延迟时间(如800ms,可按需调整),用户停止输入后延迟结束再触发搜索
  • 确保仅在主线程更新UI或调用搜索方法

完整代码实现

private CancellationTokenSource _searchCts;
private const int _searchDelayMs = 800; // 可调整延迟时间

void OnSearcMyNews(System.Object sender, Xamarin.Forms.TextChangedEventArgs e)
{
    // 获取输入框最新内容
    var currentSearchTerm = e.NewTextValue?.Trim().ToLower() ?? string.Empty;

    // 取消并释放之前的搜索任务
    _searchCts?.Cancel();
    _searchCts?.Dispose();
    
    // 空输入时直接清空结果(可选逻辑)
    if (string.IsNullOrEmpty(currentSearchTerm))
    {
        // 此处可添加清空搜索结果的代码
        return;
    }

    // 创建新的取消令牌源
    _searchCts = new CancellationTokenSource();
    var token = _searchCts.Token;

    // 延迟执行搜索
    _ = Task.Run(async () =>
    {
        try
        {
            await Task.Delay(_searchDelayMs, token);
            // 确认任务未被取消(用户未继续输入)
            if (!token.IsCancellationRequested)
            {
                await Device.InvokeOnMainThreadAsync(async () =>
                {
                    await SearchNewsDataAsync(currentSearchTerm, UserConnected.NewsLanguage);
                });
            }
        }
        catch (TaskCanceledException)
        {
            // 任务被取消,无需处理
        }
        catch (Exception ex)
        {
            // 此处可添加异常日志记录逻辑
        }
        finally
        {
            _searchCts?.Dispose();
        }
    }, token);
}

关键改进点

  • 用CancellationTokenSource精准控制任务取消,避免旧任务触发无效搜索
  • 直接从TextChangedEventArgs获取最新输入内容,避免外部变量同步问题
  • 添加空输入处理,减少无效API调用
  • 完善异常处理,避免静默吞错
  • 延迟时间设为800ms,平衡响应速度和API调用频率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 08:59:16