Xamarin调用WebAPI获取返回值时用.Result自动退出如何解决?
问题根因
- 调用异步方法时使用
.Result阻塞主线程,Xamarin的UI同步上下文会因此触发死锁:.Result会卡住UI线程等待异步任务完成,而异步任务执行完成后需要回到UI线程执行后续代码,两者互相等待导致死锁,程序直接闪退。 GetCustomersAsync内部也存在多处错误写法:调用ReadAsStringAsync时也用了.Result,存在死锁风险;方法末尾冗余使用Task.FromResult;每次请求都新建HttpClient实例,长期运行会导致套接字资源耗尽。HttpClient的地址配置写法不规范,容易引发后续请求地址拼接错误。
修复后的代码
1. 优化GetCustomersAsync方法
建议把HttpClient提为静态实例,避免重复创建:
// 把HttpClient定义为静态全局实例,不要每次请求都新建 private static readonly HttpClient _client = new HttpClient(); public async Task<Customer> GetCustomersAsync(string id) { var prod = new Customer(); try { string url = "https://xxxxxx.com/api/Customers/" + id; // 加ConfigureAwait(false)不需要回到原同步上下文,降低死锁风险 HttpResponseMessage response = await _client.GetAsync(url).ConfigureAwait(false); if (response.IsSuccessStatusCode) { // 这里也要用await,不要用.Result string content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); prod = JsonConvert.DeserializeObject<Customer>(content); } } catch (Exception ex) { // 可在此处添加日志逻辑,方便排查接口请求错误 Console.WriteLine($"请求接口出错:{ex.Message}"); } // 异步方法直接返回对象即可,不需要包Task.FromResult return prod; }
2. 修正异步方法调用逻辑
所有异步方法都要用await调用,禁止使用.Result或者.Wait():
// 注意:如果这段代码写在UI点击事件等方法里,要把对应的方法签名改成async void // 示例:原方法是 private void Button_Click(object sender, EventArgs e) 改成 private async void Button_Click(object sender, EventArgs e) var infocustomer = await customerRepository.GetCustomersAsync(userrating); // 加空值判断避免接口请求失败时空引用报错 string nameus = infocustomer?.NameUs; if(string.IsNullOrEmpty(nameus)) { // 此处添加获取数据失败的处理逻辑,比如给用户弹出提示 }
内容的提问来源于stack exchange,提问作者Chim Di Tru
相关产品推荐
相关产品推荐

