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

Xamarin Forms中HttpClient请求极慢问题求助

解决三星设备上HttpClient请求缓慢/TaskCancelledException问题

看起来你遇到的问题在Xamarin.Android开发里并不少见,尤其是在部分三星设备上。结合你的代码和描述,我整理了几个关键的排查和修复方向:

1. 修复async void的问题

你在OnStart里调用的LoadFrom是async static void方法,这种写法只适合事件处理程序,在Android生命周期方法中使用会导致:

  • 无法正确捕获异步操作的上下文,可能引发意外的任务取消
  • 异常无法被上层try/catch捕获(除非借助SynchronizationContext)

修改方案:

  • 把LoadFrom改成async static Task
  • 在OnStart里用await调用它(虽然OnStart是void,但这里用async void是生命周期方法的特例)

2. 复用HttpClient实例

你的代码每次调用LoadFrom都会新建一个HttpClient,频繁创建会耗尽系统的TCP连接池,直接导致请求变慢甚至失败。正确的做法是复用单例HttpClient。

3. 调整AndroidClientHandler的设置

部分三星设备对HTTP/2的支持有兼容性问题,禁用HTTP/2强制使用HTTP/1.1往往能解决慢请求的问题。同时设置合理的超时时间(30分钟太长了,5分钟足够测试)。

修改后的完整代码

public static class DataSource 
{
    // 全局复用HttpClient实例,避免频繁创建连接
    private static readonly HttpClient _httpClient;

    static DataSource()
    {
        var handler = new Xamarin.Android.Net.AndroidClientHandler();
        // 禁用HTTP/2,解决部分三星设备的兼容性问题
        handler.DisableHttp2 = true;
        _httpClient = new HttpClient(handler);
        // 设置合理的超时时间
        _httpClient.Timeout = TimeSpan.FromMinutes(5);
    }

    public async static Task LoadFrom() 
    { 
        var uri = new Uri("https://api.coinmarketcap.com/v2/ticker/?convert=usd&sort=price"); 
        try 
        { 
            bool isConnected = CrossConnectivity.Current.IsConnected;
            if (!isConnected)
            {
                Debug.Print("No internet connection available");
                return;
            }

            // 使用ConfigureAwait(false)避免捕获UI上下文,提升异步性能
            var response = await _httpClient.GetAsync(uri).ConfigureAwait(false); 
            // 直接抛出HTTP错误状态码,简化错误处理
            response.EnsureSuccessStatusCode();

            var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false); 
            var coinMarketCapObject = JsonConvert.DeserializeObject<CoinMarketCap.CoinMarketCapCurrencyData>(data); 

            List<Currency> currencies = new List<Currency>(); 
            if (coinMarketCapObject != null) 
            { 
                foreach (var datum in coinMarketCapObject.Data) 
                { 
                    currencies.Add(new Currency(datum.Value.name, datum.Value.symbol, datum.Value.quotes.USD.price)); 
                } 
            } 
            // 这里可以添加currencies的后续处理逻辑(比如通知UI更新)
        } 
        catch (TimeoutException ex) 
        { 
            Debug.Print($"Request timed out: {ex.Message}");
        } 
        catch (TaskCanceledException ex) 
        { 
            // 区分手动取消和超时导致的任务取消
            if (ex.CancellationToken.IsCancellationRequested)
            {
                Debug.Print("Request was cancelled manually");
            }
            else
            {
                Debug.Print("Request timed out (TaskCanceledException)");
            }
        } 
        catch (Exception e) 
        { 
            Debug.Print($"Error loading data: {e.Message}");
        } 
    } 
}

修改OnStart方法:

protected override async void OnStart ()
{
    // Handle when your app starts
    await API.DataSource.LoadFrom();
}

额外排查方向

如果修改后问题依然存在,可以试试这些方法:

  • 测试其他HTTPS接口(比如https://jsonplaceholder.typicode.com/todos/1),确认是不是目标API本身的问题
  • 检查三星设备的省电模式,部分省电策略会限制后台网络请求的速度
  • 切换设备的DNS服务器(比如改成8.8.8.8),排查是不是DNS解析缓慢导致的问题
  • 用抓包工具(比如Charles)分析请求流程,看是卡在DNS解析、TCP连接还是等待响应阶段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:07:45