Xamarin HTTP请求超时 [英] Timeouts in Xamarin HTTP requests
问题描述
晚上好!
我试图清理/改进一些代码,最终发现Xamarin HTTP请求中超时的问题(如在我的原始帖子中描述:异步下载和反序列化。)
I was trying to clean/refine some code and ended up finding issues with timeouts in Xamarin HTTP requests (as described in my original thread: Async Download and Deserialize).
发现问题(仅使用Xamarin.Android测试;不了解iOS):
当<无法访问strong>主机(例如,脱机本地服务器), GetAsync
抛出 System.Net.WebException
大致 3分钟后,消息错误:ConnectFailure(连接超时)。内部异常是 System.Net.Sockets.SocketsException
(完整记录在这里: http://pastebin.com/MzHyp2FM )。
When a host cannot be reached (e.g., an offline local server), GetAsync
throws a System.Net.WebException
after roughly 3 minutes with the message Error: ConnectFailure (Connection timed out). The Inner exception is System.Net.Sockets.SocketsException
(full log here: http://pastebin.com/MzHyp2FM).
代码:
internal static class WebUtilities
{
/// <summary>
/// Downloads the page of the given url
/// </summary>
/// <param name="url">url to download the page from</param>
/// <param name="cancellationToken">token to cancel the download</param>
/// <returns>the page content or null when impossible</returns>
internal static async Task<string> DownloadStringAsync(string url, CancellationToken cancellationToken)
{
try
{
// create Http Client and dispose of it even if exceptions are thrown (same as using finally statement)
using (var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(5) })
{
// should I always do this?
client.CancelPendingRequests();
// Issue here; Timeout of roughly 3 minutes
using (var response = await client.GetAsync(url, cancellationToken).ConfigureAwait(false))
{
// if response was successful (otherwise return null)
if (response.IsSuccessStatusCode)
{
// return its content
return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
}
}
}
// TODO: split exceptions?
catch (Exception ex) when (ex is System.Net.Sockets.SocketException ||
ex is InvalidOperationException ||
ex is OperationCanceledException ||
ex is System.Net.Http.HttpRequestException)
{
WriteLine("DownloadStringAsync task has been cancelled.");
WriteLine(ex.Message);
return null;
}
// return null if response was unsuccessful
return null;
}
}
通话方式:
internal static async Task CallAsync(string url)
{
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)))
{
var token = cts.Token;
token.ThrowIfCancellationRequested();
string result = await WebUtilities.DownloadStringAsync(url, token).ConfigureAwait(false);
}
}
设置客户端.Timeout
似乎不起作用。
Setting client.Timeout
doesn't seem to work.
无论哪种方式,不应该在10秒后自动取消cancelToken ?
此超时问题发生在:
- 请求离线/无法访问的IP地址(在我的情况下是离线本地服务器
,如192.168.1.101:8080)(即使用GetAsync
,SendAsync
,
GetResponseAsync
)
- An offline/unreachable IP address (in my case an offline local server
such as 192.168.1.101:8080) is requested (i.e., using
GetAsync
,SendAsync
,GetResponseAsync
)
代码在以下情况下运作良好:
- 请求来自桌面客户端(例如, WPF )。如果
IP离线/无法访问,它会非常快地抛出4个异常(无法建立连接,因为目标计算机主动拒绝它)。
- The request is made from a desktop client (e.g., WPF). If the IP is offline/unreachable it throws 4 exceptions really fast (No connection could be made because the target machine actively refused it).
结论
Xamarin似乎在Http请求中有一些错误(至少有超时?),因为他们没有给出预期的结果。从我所看到的情况来看,它可能已经存在了几年(自2012年或2013年)。
Xamarin seems to have some bugs in Http requests (with Timeouts at least?), as they do not give the expected results. And from what I have read, it could be something that has been around for few a years (since 2012 or 2013).
Xamarin单元测试并没有真正帮助: https ://github.com/xamarin/xamarin-android/blob/1b3a76c6874853049e89bbc113b22bc632ed5ca4/src/Mono.Android/Test/Xamarin.Android.Net/HttpClientIntegrationTests.cs
Xamarin unit testing doesn't really help either: https://github.com/xamarin/xamarin-android/blob/1b3a76c6874853049e89bbc113b22bc632ed5ca4/src/Mono.Android/Test/Xamarin.Android.Net/HttpClientIntegrationTests.cs
修改
-
超时= TimeSpan.FromMilliseconds(1000)
- 作品 -
超时=超时= TimeSpan.FromSeconds(1)
- 不起作用(???? ?) -
Timeout = TimeSpan.FromMilliseconds(2000)
(及以上) - 不是
work
Timeout = TimeSpan.FromMilliseconds(1000)
- worksTimeout = Timeout = TimeSpan.FromSeconds(1)
- doesn't work (?????)Timeout = TimeSpan.FromMilliseconds(2000)
(and above) - doesn't work
有什么想法吗?谢谢!
推荐答案
我发现更改Android的http客户端设置解决了我的问题!我在这里发布了更多详细信息: http://jeremei.com/xamarinvisual-studio-httpclient -request-timeout /
I found that that changing the http client settings for Android resolved my issue! I posted more details here: http://jeremei.com/xamarinvisual-studio-httpclient-request-timeout/
这篇关于Xamarin HTTP请求超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!