Xamarin Forms依赖注入的HttpClient在API宕机时超时设置不生效
问题根因
HttpClient的Timeout属性仅作用于已成功建立TCP连接后的请求响应阶段,无法控制TCP连接建立、DNS解析阶段的超时。你遇到的2分钟等待是Xamarin运行时对应平台底层HTTP处理程序的默认连接超时,该配置不会跟随HttpClient的Timeout属性自动生效。
而每次手动新建HttpClient时会同步创建新的底层HTTP处理程序,新建实例的连接逻辑会快速判断目标端口不可用,因此会在短时间内抛出连接拒绝异常,和你预期的表现一致。
解决方案
方案1:配置HTTP处理程序的连接超时
在注册HttpClient时显式指定各平台原生处理程序的连接超时参数,和HttpClient的Timeout保持一致,修改Startup.cs中的ConfigureServices方法:
static void ConfigureServices(HostBuilderContext ctx, IServiceCollection services) { services.AddHttpClient("", client => { client.Timeout = TimeSpan.FromSeconds(10); }) .ConfigurePrimaryHttpMessageHandler(() => { #if ANDROID return new Xamarin.Android.Net.AndroidClientHandler { ConnectTimeout = TimeSpan.FromSeconds(10) }; #elif IOS return new Foundation.NSUrlSessionHandler { TimeoutIntervalForRequest = 10, TimeoutIntervalForResource = 10 }; #else return new HttpClientHandler(); #endif }); services.AddSingleton<IMyAppService, MyAppService>(); services.AddTransient<MainViewModel>(); }
方案2:用CancellationToken实现全阶段超时控制(更稳妥)
不管底层配置如何,通过取消令牌主动控制请求的最大等待时间,覆盖连接、请求、响应读取全阶段,修改MyAppService.cs的CallApiAsync方法:
public async Task<string> CallApiAsync() { // 10秒后自动触发取消 using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); try { var response = await httpClient.GetAsync("YOUR API CALL HERE", cts.Token); if (response.IsSuccessStatusCode) { return await response.Content.ReadAsStringAsync(cts.Token); } return null; } catch (OperationCanceledException) { // 超时触发,抛出你需要的异常信息 throw new HttpRequestException("No connection could be made because the target machine actively refused it..."); } }
两种方案任选其一即可解决API宕机时超时不生效的问题,优先推荐方案2,兼容性更强,不受平台底层默认配置影响。
内容的提问来源于stack exchange,提问作者user2506790
相关产品推荐
相关产品推荐

