Я немного озадачен всеми этими проблемами и обходными путями использования httpclient в xamarin.forms. Я хотел бы обобщить свое понимание и колебания / вопросы
- Утилизация каждый раз против Singleton HttpClient и Static Client: Говорят, что не используйте использование вокруг httpClient и не используйте реализацию singleton, как указано в этой статье
Неправильный;
var httpClient = new HttpClient(new HttpClientHandler
{
//Some settings
});
Правильно:
public class HttpService
{
private readonly HttpClient _httpClient;
public HttpService()
{
_httpClient = CreateHttpClient();
}
Здесь первый вопрос, если мы не используем static
в чем преимущество этого?
Потому что HttpService будет запускать новый клиент для каждого потока, не так ли? Если мы используем статический клиент, это вызовет какой-либо цикл памяти?
Xamarin формы очень хрупки по отношению к статической зависимости, если вы держите статическое значение внутри ViewModel и ViewModel связан с View с использованием Freshmvvm, Prism и т. Д., Обычно View не удаляется, а экземпляр остается в памяти и вызывает утечку памяти даже после выталкивания страница.
Проблема с изменениями DNS: похоже, что существует проблема при использовании одноэлементного HttpClient при изменении DN, как описано здесь . Как преодолеть эту проблему в приложении xamarin.forms? Я не вижу ни одного ServicePointManager, определенного в стандарте .net 2.0. Мне действительно нужно беспокоиться об этом?
ReadAsStreamAsync против ReadAsStringAsync при получении ответа. Имеет ли большое значение использование ReadAsStreamAsync? и есть ли побочный эффект для использования в качестве потока?
Должны ли мы использовать HttpResponseMessage с использованием, как показано ниже?
использование (HttpResponseMessage response = await client.GetAsync (uri))
{
if (! response.IsSuccessStatusCode)
{
//Сделай что-нибудь
}
еще
{
//Сделай что-нибудь
}
}
Наконец, мой класс выглядит так, как показано ниже; Вы видите какие-либо проблемы с этим?
настройки прокси описаны в этой статье
namespace myApp
{
public class HttpService
{
private readonly HttpClient client;
private JsonSerializer _serializer = new JsonSerializer();
public HttpService()
{
if (client == null)
{
try
{
HttpClientHandler handler = new HttpClientHandler
{
Proxy = Xamarin.Forms.DependencyService.Get<IProxyInfoProvider>().GetProxySettings()
};
client = new HttpClient(handler);
}
catch (Exception ex)
{
}
}
}
public async Task<T> GetItemAsync<T>(string url, CancellationToken cancellationToken=default(CancellationToken))
{
T returnObject = default(T);
Uri uri = new Uri(url);
try
{
using (HttpResponseMessage response = await client.GetAsync(uri,cancellationToken))
{
if (!response.IsSuccessStatusCode)
{
//Handle error
}
else
{
returnObject = await getReturnObject<T>(response);
}
}
}
catch (OperationCanceledException)
{
}
catch (System.Net.Http.HttpRequestException)
{
}
catch (Exception ex)
{
}
return returnObject;
}
public async Task<T> getReturnObject<T>(HttpResponseMessage response)
{
T returnObject = default(T);
if (response.IsSuccessStatusCode)
{
using (System.IO.Stream stream = await response.Content.ReadAsStreamAsync())
using (System.IO.StreamReader reader = new System.IO.StreamReader(stream))
using (JsonTextReader json = new JsonTextReader(reader))
{
returnObject = _serializer.Deserialize<T>(json);
}
//string content = await response.Content.ReadAsStringAsync();
//returnObject = JsonConvert.DeserializeObject<T>(content);
}
return returnObject;
}
}
}