Xamarin.Android HTTP 随机延迟
Posted
技术标签:
【中文标题】Xamarin.Android HTTP 随机延迟【英文标题】:Xamarin.Android HTTP Random Delays 【发布时间】:2017-01-21 20:37:10 【问题描述】:我有一个执行多个 HTTP 请求的方法,称为 LoadServers()
一个执行 LoadServers()
的按钮。对于我的问题,我只在之前的LoadServers()
通话完成后点击按钮。加载时会出现一个进度对话框,因此我只能连续执行它们。
大约每 10 到 15 次调用 LoadServers
会导致第一个 http 请求延迟几乎正好 10 秒。 LoadServers
完成的平均时间不到半秒,从不超过 1 秒。这只发生在 Xamarin.android 上。 Xamarin.ios 上不会发生延迟,并且所有这些代码都是共享的。
这是我的代码
private async Task LoadServers()
await Get();
await Post();
await Get();
await Get();
await Post();
private async Task Get()
var url = _httpClient.BaseAddress + model.GetToken();
Log("Attempting to send GET to: " + url);
using (var response = await _httpClient.GetAsync(url))
var resultContent = await response.Content.ReadAsStringAsync();
Log("Got response back from : " + url + ": " + resultContent);
private async Task Post()
var content = requestData.GetToken() + "=" + requestData.PostBody ();
var request = new StringContent(content)
Headers = ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded")
;
var url = _httpClient.BaseAddress + "/No_content";
Log ("Attempting to send POST to: " + url + " with content: " + content);
using (var response = await _httpClient.PostAsync(url, request))
string resultContent = await response.Content.ReadAsStringAsync();
Log("Got response back from : " + url + ": " + resultContent);
LoadServers()
每执行 15 次左右就会产生以下日志语句:
Thread started: #37
Thread finished: #37
[2017-01-21T13:42:30.8841620-06:00] [debug] Loading Servers
[2017-01-21T13:42:30.8946770-06:00] [debug] Attempting to send GET to: XXX
Thread finished: <Thread Pool> #23
Thread started: <Thread Pool> #38
[2017-01-21T13:42:40.9550360-06:00] [debug] Got response back from : XXX <-- Notice the time (~10 seconds)
这是否与 HTTP 请求的资源消耗有关?它会尝试清理资源并暂停执行,直到发生这种情况?我不确定它执行请求时会发生什么。它会启动一个新线程吗?
【问题讨论】:
我无法重现您的问题,但我发现您的代码存在两个问题。 1. 由于您在Get()
和Post()
方法中使用关键字await
进行线程工作,那么这两个方法应该是async
。 2.这两种方法不是任务,它们是无效的,你不需要/不能await
它们在你的任务LoadServers
中。我不知道你是如何让你的代码运行的,在我身边,我需要修改你的代码,但我仍然无法重现你的问题。为了隔离设备问题,您可以使用模拟器或其他安卓设备来测试您的代码。
嗨@GraceFeng-MSFT,感谢您的回复。当我清理代码时,我不小心将它们设置为 void,而不是 Task
。我编辑了这个问题。这是通过本地网络并连接到本地设备。因此,设备响应所需的时间通常为 10-30 毫秒。这发生在许多不同的设备和许多不同的 Android OS API 级别上。由于它不会在 iOS 上使用完全相同的代码发生,因此我认为它与 Android 相关。
@kevskree,尝试在 Mac 上的控制台应用程序中运行相同的代码,以从等式中删除移动 SDK。接下来,在bugzilla.xamarin.com/enter_bug.cgi?product=Android 提交问题,并附上我们可以用来尝试和重现的示例。您可以包含一个示例作为私人附件。包括我们可能需要在本地进行设置的任何详细信息。
@therealjohn 感谢您的建议。我只能使用控制台应用程序与 Android 应用程序制作示例。我无法在控制台应用程序上重现它,并且延迟仍然发生在 Android 上。我将在 bugzilla 中编写一个错误。感谢您的帮助。
【参考方案1】:
找出确切的问题很困难,而且我无法重现它。但是,System.Net
和 HttpClient
中的默认 MessageHandler 的包装并未完全优化。因此,您猜测可能是资源问题。
尝试使用 ModernHttpClient (Xamarin Component | Nuget | Developer Review | Github),并在构造函数中为您添加 NativeMessageHandler
HttpClient
。这将使用一些优化的原生库(对于 Android,它是 OkHttp
),这将有助于提高性能。
【讨论】:
他们不是将 ModernHttpClient 构建到最新版本的 Xamarin.Android 中吗? 他们提高了它的性能,但OkHttp
更进一步。此外,仅当从 Xamarin.Android 项目的代码而不是从 PCL 调用它时。 PCL 将使用不使用新处理程序的内置 .NET Portable HttpClient。【参考方案2】:
我尝试了同样的问题。 我正在使用 xamarin.android 6.6.1.2-21 并支持 Api 23 的东西。
我发现在您第一次调用之前使用 默认 httpHandler 并创建 2 个 httpClients 可以解决此问题。
new HttpClient( new Xamarin.Android.Net.AndroidClientHandler());
并在代码中开始任何实际调用之前创建 2 个 httpclients。
还将“HttpClient implementation”设置为“AndroidClientHandler”。您可以在以下位置找到此选项:项目选项 > Android 构建 > 代码生成和运行时。 这仅适用于 android 5+
http implementation option
【讨论】:
您的意思是直接调用var client = new HttpClient(new Xamarin.Android.Net.AndroidClientHandler()); client = new HttpClient(new Xamarin.Android.Net.AndroidClientHandler());
即可解决问题?
格式化您的代码。 meta.***.com/questions/251361/…
是的。在创建将用于创建getAsync()
或postAsync()
的httpClient 之前创建两个httpclient。还将“HttpClient implementation”设置为“AndroidClientHandler”。您可以在项目选项> Android 构建>代码生成和运行时找到此选项。
不幸的是,在代码或项目设置中使用 Android 客户端处理程序会导致我的 HTTP 请求执行速度极慢。通常请求需要
这真的很奇怪。它应该更快。您是从 Android 还是从 PCL 创建 httpclient?以上是关于Xamarin.Android HTTP 随机延迟的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin.Android RunOnUIThread 和 onTimedEvent 延迟/滞后(我正在尝试显示倒数计时器)
Xamarin.Android WebView App性能问题
向 Xamarin Android 添加新图像会更改所有其他图像