2017-01-21 3 views
4

У меня есть метод, который выполняет несколько HTTP-запросов, называемых LoadServers() Кнопка, которая выполняет LoadServers(). Для моей проблемы я нажимаю кнопку только после завершения предыдущего вызова LoadServers(). Во время загрузки появляется диалог выполнения, поэтому я могу выполнять их только последовательно.Xamarin.Android HTTP Случайные задержки

Один раз примерно каждые 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); 
    } 
} 

Каждый 15 или так расстрелы LoadServers() приводит следующие утверждения журнала:

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? Он пытается очистить ресурсы и приостановить выполнение до тех пор, пока это не произойдет? Я не уверен, что произойдет, когда он выполнит запрос. Открывает ли он новый поток?

+0

Я не могу воспроизвести проблему, но я нашел две проблемы с кодом. 1. Так как вы выполняете работу потока в методах 'Get()' и 'Post()', используя ключевое слово 'await', то эти два метода должны быть' async'. 2. эти два метода не являются задачами, и они недействительны, вам не нужно/не может «ждать» их в вашей задаче «LoadServers». Я не знаю, как вы заставляете свой код работать, на моей стороне мне нужно изменить код, но я не смог воспроизвести вашу проблему. Чтобы изолировать проблему устройства, вы можете использовать эмулятор или другое устройство Android для проверки кода. –

+0

Привет @ GraceFeng-MSFT, Спасибо за ответ. Когда я очищал код, я случайно ставил их как void вместо 'Task'. Я редактировал вопрос. Это происходит по локальной сети и подключается к локальному устройству.Таким образом, время, которое обычно требуется устройству для ответа, составляет 10-30 миллисекунд. Это происходит на многих разных устройствах и на разных уровнях API Android OS. Так как это не происходит на iOS с тем же кодом, я думаю о нем с Android. – kevskree

+0

@kevskree, попробуйте запустить тот же код в консольном приложении на вашем Mac, чтобы удалить мобильные SDK из уравнения. Затем напишите вопрос по адресу https://bugzilla.xamarin.com/enter_bug.cgi?product=Android с образцом, который мы можем использовать, чтобы попытаться воспроизвести. Вы можете включить образец как частное приложение. Включите любые детали, которые могут потребоваться, чтобы установить это локально. – therealjohn

ответ

2

Выявление точной проблемы является жестким, и я не могу воспроизвести его. Однако обертка System.Net и MessageHandler по умолчанию в HttpClient не полностью оптимизирована. Таким образом, ваше предположение о том, что это проблема ресурса, может быть так.

Попробуйте использовать ModernHttpClient (Xamarin Component | Nuget | Developer Review | Github), и добавление NativeMessageHandler в конструкторе для вас HttpClient. Это будет использовать некоторые оптимизированные родные библиотеки (для Android, это OkHttp), которые помогут в производительности.

+0

Разве они по существу не построили ModernHttpClient в последней версии Xamarin.Android? –

+0

Они увеличили свою производительность, но «OkHttp» делает это еще дальше. Кроме того, это было бы только при вызове его из кода проекта Xamarin.Android, а не из PCL. PCL будет использовать встроенный .NET Portable HttpClient, который не использует новый обработчик. – SuavePirate

+0

О, круто, не понял. Я буду использовать его тогда :) –

0

Я экспериментировал с той же проблемой. я использую xamarin.android поддержки 6.6.1.2-21 и материал для Апи 23.

я обнаружил, что с помощью по умолчанию HttpHandler и создание 2 httpClients перед первым вызовом решить эту проблему.

new HttpClient(new Xamarin.Android.Net.AndroidClientHandler()); 

и создать 2 httpclients перед началом любого реального вызова в вашем коде.

Также настройте реализацию «HttpClient» на «AndroidClientHandler». Вы можете найти эту опцию: Параметры проекта> Android build> Генерация кода и время выполнения. Это только работа на андроид 5+

http implementation option

+0

Вы имеете в виду просто вызов '' 'var client = new HttpClient (новый Xamarin.Android.Net.AndroidClientHandler()); client = new HttpClient (новый Xamarin.Android.Net.AndroidClientHandler()); '' ' устраняет проблему? – kevskree

+0

отформатируйте свои коды. https://meta.stackoverflow.com/questions/251361/how-do-i-format-my-code-blocks – IsuruAb

+0

Да. Создайте два httpclient перед созданием httpClient, который вы будете использовать для создания 'getAsync()' или 'postAsync()'. Также установите «реализация HttpClient» на «AndroidClientHandler». Этот параметр можно найти в разделе «Параметры проекта»> «Андроид»> «Генерация кода» и «Время выполнения». –

Смежные вопросы