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】:在发出请求之前修改名为cliente
的HttpClient
的超时时间,并在请求周围添加一个try/catch
块以查看发生了什么。
如果您有单独的异步方法进行调用,您可以将 try/catch 放在那里,然后调用单独的方法。否则,在对任务进行异常处理之前调用.Wait()
。 Wait()
将用于测试目的,而非生产用途。
【讨论】:
以上是关于GetStringAsync 持续时间过长且永不返回的主要内容,如果未能解决你的问题,请参考以下文章
分析一个达到 100% CPU 且永不结束的 ruby 应用程序
关于Hbase的RegionServer的GC持续时间过长解决办法
windows phone 8.1 中 HttpClient.GetStringAsync 方法的问题