GetStringAsync 持续时间过长且永不返回

Posted

技术标签:

【中文标题】GetStringAsync 持续时间过长且永不返回【英文标题】:GetStringAsync last too long and never returns 【发布时间】:2019-08-13 17:07:27 【问题描述】:

我正在开发和使用 API 的应用程序(使用 genymotion 模拟器进行测试),我制作了一个简单的测试内容页面,其中包含以下代码:

using PlaqueoApp.Modelos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Net.NetworkInformation;
using Newtonsoft.Json;

namespace PlaqueoApp

    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class RegistrarPatron : ContentPage
    
        public RegistrarPatron ()
        
            InitializeComponent ();

            GetOficinas().Wait();

        

        private async Task GetOficinas()
        
            Ping myPing = new Ping();
            PingReply reply = myPing.Send("8.8.8.8", 10000);


            HttpClient cliente = new HttpClient();

            string url = "https://reqres.in/api/users?page=2";

            var response = await cliente.GetStringAsync(url);

            var anonimus = JsonConvert.DeserializeObject<List<object>>(response);


        
    

我的问题是,当它到达 GetStringAsync 时,它会永远持续下去,我的意思是,方法调用永远不会返回,我必须停止它。 响应应该是这样的:


  "page": 2,
  "per_page": 3,
  "total": 12,
  "total_pages": 4,
  "data": [
    
      "id": 4,
      "email": "eve.holt@reqres.in",
      "first_name": "Eve",
      "last_name": "Holt",
      "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg"
    ,
    
      "id": 5,
      "email": "charles.morris@reqres.in",
      "first_name": "Charles",
      "last_name": "Morris",
      "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg"
    ,
    
      "id": 6,
      "email": "tracey.ramos@reqres.in",
      "first_name": "Tracey",
      "last_name": "Ramos",
      "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg"
    
  ]
 

我以为是因为 Iternet 连接,但我检查了 Gennymotion 模拟器,并且启用了 WIFI 选项。如您所见,我还对谷歌进行了 ping 操作,我获得了成功状态,我还在清单上添加了 Internet 权限。 我不知道我是否遗漏了什么,是否在调试我的应用程序或其他任何东西

【问题讨论】:

嗨,我的问题是,流程永远不会到达那里,就像它在等待 Get 请求时永远不会完成 尝试在模拟器的浏览器中加载url 你不应该使用.Wait(),这将阻塞直到任务完成。我假设此应用程序正在使用与 Windows 如何执行此操作相关的同步上下文,基于消息。由于您在任务完成之前有效地阻塞了主线程,因此任务的完成会使要执行的操作排队,并且永远不会执行,因为您正在阻塞消息和事件的处理。删除 .Wait() 并找到一种更好的异步方式来做你想做的事。 嗨@LasseVågsætherKarlsen。问题是当流到达 GetStringAsync 时它没有完成(当我调试时它得到我们的方法或完成 ir),我认为是因为主线程继续,因为客户端正在等待响应。 这个问题几乎可以肯定是由于等待,您阻塞了同步上下文,这意味着任务将永远处于不确定状态。 【参考方案1】:

不要这样做:

        public RegistrarPatron ()
        
            InitializeComponent ();

            GetOficinas().Wait();
        

您几乎不应该在这样的任务上等待():它会冻结您的应用程序或永远阻塞线程。

改为这样做:

namespace PlaqueoApp

    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class RegistrarPatron : ContentPage
    
        public RegistrarPatron ()
        
            InitializeComponent ();
        

        protected override async void OnAppearing()
        
            try 
            
                await GetOficinas();
            
            catch (Exception exception)
            
                Debug.WriteLine(e.ToString());
               
        

        private async Task GetOficinas()
        
            Ping myPing = new Ping();
            PingReply reply = myPing.Send("8.8.8.8", 10000);

            HttpClient cliente = new HttpClient();

            string url = "https://reqres.in/api/users?page=2";

            var response = await cliente.GetStringAsync(url);

            var anonimus = JsonConvert.DeserializeObject<List<object>>(response);
        
    

【讨论】:

非常感谢,它成功了,只是我已经删除了 .Wait() 并且没有成功,我不知道这是不是网络适配器的问题。 @MaxPower:这里解释一下locking on asynchronous code can cause deadlocks.【参考方案2】:

在发出请求之前修改名为clienteHttpClient 的超时时间,并在请求周围添加一个try/catch 块以查看发生了什么。

如果您有单独的异步方法进行调用,您可以将 try/catch 放在那里,然后调用单独的方法。否则,在对任务进行异常处理之前调用.Wait()Wait() 将用于测试目的,而非生产用途。

【讨论】:

以上是关于GetStringAsync 持续时间过长且永不返回的主要内容,如果未能解决你的问题,请参考以下文章

删除时间过长且未完成

分析一个达到 100% CPU 且永不结束的 ruby​​ 应用程序

关于Hbase的RegionServer的GC持续时间过长解决办法

windows phone 8.1 中 HttpClient.GetStringAsync 方法的问题

HttpClient GetStringAsync - 它永远不会回来

Cocos2dx 2.1.4 游戏,Continuos FPS 下降且永不恢复