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

为移动应用Web服务调用任务添加超时机制避免任务取消

解决Web服务调用超时及任务取消问题

你的核心问题是Web服务响应过慢导致任务被系统取消,还没法正常检查响应状态码。我们可以从给Web请求添加可控超时机制和优化异常处理、性能两个维度来解决,下面一步步来调整代码:

1. 在HelperFile中添加自定义超时逻辑

原来的GetResponseString依赖HttpClient默认超时(100秒),但系统可能因为等待过久直接取消任务,导致你拿不到响应对象。改用Task.WhenAny结合延迟任务的方式,既能自定义超时时间,还能确保在请求完成或超时后都能明确处理,不会丢失响应码的检查机会。

修改后的HelperFile代码:

public class HelperFile
{
    // 自定义超时时间,比如设置为30秒,可根据需求调整
    private readonly TimeSpan _requestTimeout = TimeSpan.FromSeconds(30);

    public async Task<string> GetResponseString(Uri url)
    {
        using (HttpClient client = new HttpClient())
        {
            // 同时启动Web请求和超时等待任务
            var requestTask = client.GetAsync(url);
            var timeoutTask = Task.Delay(_requestTimeout);

            // 等待先完成的任务
            var completedTask = await Task.WhenAny(requestTask, timeoutTask);

            if (completedTask == timeoutTask)
            {
                // 触发超时,抛出明确的超时异常,方便上层处理
                throw new TimeoutException("Web服务请求超时,请稍后重试");
            }
            else
            {
                // 请求正常完成,获取响应并检查状态码
                using (HttpResponseMessage response = await requestTask)
                {
                    if (response.IsSuccessStatusCode)
                    {
                        using (HttpContent content = response.Content)
                        {
                            return await content.ReadAsStringAsync();
                        }
                    }
                    else
                    {
                        // 抛出包含状态码的异常,让上层知道具体HTTP错误
                        throw new HttpRequestException($"请求失败,状态码:{(int)response.StatusCode}");
                    }
                }
            }
        }
    }
}

为什么选这种方式?

  • 比直接设置client.Timeout更灵活:能在超时前做自定义处理,还能区分"主动取消任务"和"超时"两种不同场景
  • 确保你一定能拿到响应对象(只要请求没超时),不会因为系统强制取消任务而丢失响应码的检查机会

2. 优化ProcessData的异常处理与性能

原来的代码还有两个小问题:每次循环都创建SQLite连接(性能浪费),以及没有针对性捕获超时/HTTP异常,导致错误信息模糊。调整后的代码:

private async Task ProcessData()
{
    try
    {
        HelperFile myHelper = new HelperFile();
        Uri jsonUrl1 = new Uri("https://www.myURL.com/page.asmx/GetMyData");
        var result = await myHelper.GetResponseString(jsonUrl1);

        jsonCredit_Union.RootObject obj = JsonConvert.DeserializeObject<jsonCredit_Union.RootObject>(result);

        // 把SQLite连接移到循环外,减少连接创建销毁的开销
        using (SQLiteConnection conn = new SQLiteConnection(App.DB_PATH))
        {
            conn.CreateTable<tblCredit_Union>();
            foreach (KeyValuePair<string, jsonCredit_Union.JobCode> kvp in obj.Results.JobCodes)
            {
                tblCredit_Union tcu = new tblCredit_Union()
                {
                    cuName = kvp.Value.cuName,
                    cuPhone = kvp.Value.cuPhone,
                    address1 = kvp.Value.address1,
                    city = kvp.Value.city,
                    state_id = kvp.Value.state_id,
                    zip_Code = kvp.Value.zip_Code,
                    longitude = kvp.Value.longitude,
                    latitude = kvp.Value.latitude
                };
                conn.Insert(tcu);
            }
        }
    }
    catch (TimeoutException ex)
    {
        // 专门处理超时情况,比如提示用户或添加重试逻辑
        Console.WriteLine($"请求超时:{ex.Message}");
        // 示例:最多重试3次
        // for (int i = 0; i < 3; i++) { /* 重试逻辑 */ }
    }
    catch (HttpRequestException ex)
    {
        // 处理HTTP错误,比如404、500等
        Console.WriteLine($"HTTP请求错误:{ex.Message}");
    }
    catch (Exception ex)
    {
        // 兜底处理其他异常
        Console.WriteLine($"发生未知错误:{ex.Message}");
    }
}

3. 简化OnAppearing中的异步调用

原来的Task.Run属于多余的线程切换,直接调用异步方法即可:

protected async override void OnAppearing()
{
    base.OnAppearing();
    await ProcessData();
}

这样调整后,你就能:

  • 精准控制Web请求的超时时间,避免任务被系统无故取消
  • 正常检查响应码,区分成功、HTTP错误、超时三种场景
  • 优化SQLite操作性能,减少不必要的连接开销
  • 清晰捕获并处理各类异常,不再只看到模糊的"Task was cancelled"提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:29:36