【问题标题】:GetStringAsync last too long and never returnsGetStringAsync 持续时间过长且永不返回
【发布时间】: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),我认为是因为主线程继续,因为客户端正在等待响应。
  • 这个问题几乎可以肯定是由于等待,您阻塞了同步上下文,这意味着任务将永远处于不确定状态。

标签: c# xamarin.forms xamarin.android httpclient


【解决方案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);
        }
    }
}

【讨论】:

【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    • 2014-11-21
    相关资源
    最近更新 更多