Как реализовать HttpClient в приложениях Xamarin.Forms, используя лучший процессор и память? - PullRequest
0 голосов
/ 20 ноября 2018

Я немного озадачен всеми этими проблемами и обходными путями использования httpclient в xamarin.forms. Я хотел бы обобщить свое понимание и колебания / вопросы

  1. Утилизация каждый раз против 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 не удаляется, а экземпляр остается в памяти и вызывает утечку памяти даже после выталкивания страница.

  1. Проблема с изменениями DNS: похоже, что существует проблема при использовании одноэлементного HttpClient при изменении DN, как описано здесь . Как преодолеть эту проблему в приложении xamarin.forms? Я не вижу ни одного ServicePointManager, определенного в стандарте .net 2.0. Мне действительно нужно беспокоиться об этом?

  2. ReadAsStreamAsync против ReadAsStringAsync при получении ответа. Имеет ли большое значение использование ReadAsStreamAsync? и есть ли побочный эффект для использования в качестве потока?

  3. Должны ли мы использовать 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;
        }


    }
}
...