【发布时间】:2016-09-01 12:37:41
【问题描述】:
我有以下代码使用 Xamarin 和 Android 设备向 REST API 发出请求:
public class ApiBase
{
HttpClient m_HttpClient;
public ApiBase(string baseAddress, string username, string password)
{
if (!baseAddress.EndsWith("/"))
{
baseAddress += "/";
}
var handler = new HttpClientHandler();
if (handler.SupportsAutomaticDecompression)
{
handler.AutomaticDecompression = DecompressionMethods.GZip;
}
m_HttpClient = new HttpClient(handler);
m_HttpClient.BaseAddress = new Uri(baseAddress);
var credentialsString = Convert.ToBase64String(Encoding.UTF8.GetBytes(username + ":" + password));
m_HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", credentialsString);
m_HttpClient.Timeout = new TimeSpan(0, 0, 30);
}
protected async Task<XElement> HttpGetAsync(string method)
{
try
{
HttpResponseMessage response = await m_HttpClient.GetAsync(method);
if (response.IsSuccessStatusCode)
{
// the request was successful, parse the returned string as xml and return the XElement
var xml = await response.Content.ReadAsAsync<XElement>();
return xml;
}
// the request was not successful -> return null
else
{
return null;
}
}
// some exception occured -> return null
catch (Exception)
{
return null;
}
}
}
如果我有这样的情况,对 HttpGetAsync 的第一次和第二次调用可以完美运行,但从第三次开始,GetAsyncstalls 并最终由于超时而引发异常。我连续发送这些调用,它们中没有两个同时运行,因为需要前一个调用的结果来决定下一个调用。
我尝试使用应用程序数据包捕获来查看请求和响应,以确定我是否发送了错误的请求。但是看起来最终失败的请求甚至从未发送过。
通过实验我发现如果不设置AutomaticDecompression,一切正常。
如果我将HttpGetAsync 方法更改为此,它也可以正常工作:
protected async Task<XElement> HttpGetAsync(string method)
{
try
{
// send the request
var response = await m_HttpClient.GetStringAsync(method);
if (string.IsNullOrEmpty(response))
{
return null;
}
var xml = XElement.Parse(response);
return xml;
}
// some exception occured -> return null
catch (Exception)
{
return null;
}
}
所以基本上使用我 m_HttpClient.GetStringAsync 而不是 m_HttpClient.GetAsync 然后更改它周围的绒毛以使用不同的返回类型。如果我这样做,一切都会顺利进行。
有谁知道为什么GetAsync 不能正常工作(似乎没有发送第三个请求)与AutomaticDecompression,而GetStringAsync 工作完美?
【问题讨论】:
-
HTTP 客户端的错误很少,而且它不使用本机处理程序。我使用更快的现代 Http 客户端。
标签: android xamarin dotnet-httpclient