2017-01-21 1 views
4

LoadServers()LoadServers()을 실행하는 버튼이라는 여러 HTTP 요청을 실행하는 메소드가 있습니다. 내 문제의 경우 이전 LoadServers() 통화가 완료되면 버튼을 살짝 누르십시오. 로딩 중에 진행 대화 상자가 나타나서 순차적으로 만 실행할 수 있습니다.Xamarin.Android HTTP Random Delays

약 10-15 회에 한 번씩 LoadServers을 호출하면 첫 번째 HTTP 요청이 거의 정확히 10 초 동안 지연됩니다. LoadServers의 평균 소요 시간은 0.5 초 미만이며 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 태스크에서 태스크를 기다릴 필요가 없습니다. 코드 실행 방법을 모르지만 내 편에서는 코드를 수정해야하지만 여전히 문제를 재현 할 수는 없습니다. 장치 문제를 분리하기 위해 에뮬레이터 또는 기타 안드로이드 장치를 사용하여 코드를 테스트 할 수 있습니다. –

+0

안녕하세요 @ GraceFeng-MSFT, 답변 해 주셔서 감사합니다. 코드를 정리할 때 실수로 'Task' 대신 공백으로 처리했습니다. 나는 그 질문을 편집했다. 이것은 로컬 네트워크를 통해 로컬 장치에 연결하는 것입니다.따라서 대개 장치가 응답하는 데 걸린 시간은 10-30 밀리 초입니다. 이는 여러 기기 및 다양한 Android OS API 수준에서 발생합니다. 동일한 코드로 iOS에서 발생하지 않으므로 Android로 생각하고 있습니다. – kevskree

+0

@kevskree에서 Mac의 콘솔 응용 프로그램에서 동일한 코드를 실행하여 방정식에서 모바일 SDK를 제거해보십시오. 그런 다음 시도하고 재현 할 수있는 샘플로 https://bugzilla.xamarin.com/enter_bug.cgi?product=Android에서 문제를 제기하십시오. 샘플을 개인용 첨부 파일로 포함시킬 수 있습니다. 로컬로 설정하는 데 필요한 세부 정보를 포함하십시오. – therealjohn

답변

2

정확한 문제를 파악하는 것은 힘들며 재현 할 수 없습니다. 그러나 System.Net의 랩핑과 HttpClient의 기본 MessageHandler는 완전히 최적화되지 않았습니다. 그래서 리소스 문제가되는 것 같아요. (| Nuget | Developer Review | GithubXamarin Component), 그리고 HttpClient의 생성자에서 NativeMessageHandler를 추가 ModernHttpClient를 사용

보십시오. 이렇게하면 성능에 도움이되는 최적화 된 네이티브 라이브러리 (Android 용, OkHttp)가 사용됩니다.

+0

ModernHttpClient를 근본적으로 Xamarin.Android의 최신 버전에 구축하지 않았습니까? –

+0

그들은 성능을 향상 시켰지만,'OkHttp'는 한 걸음 더 나아갔습니다. 또한 PCL이 아닌 Xamarin.Android 프로젝트 코드에서 호출하는 경우에만 해당됩니다. PCL은 새 처리기를 사용하지 않는 .NET 휴대용 HttpClient를 사용합니다. – SuavePirate

+0

오, 멋지다, 깨닫지 못했다. 나는 그때 그것을 계속 사용할 것이다. –

0

나는 동일한 문제를 실험했다. 내가 API 광고 (23)

에 대한 6.6.1.2-21 및 지원 물건을 xamarin.android 사용하고 난 기본 HttpHandler를를 사용하여 첫 번째 호출하기 전에 2 httpClients를 만드는 것이이 문제를 해결할 수 있음을 발견했다.

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

두 개의 httpclients를 만들고 코드에서 실제 호출을 시작하십시오.

또한 "HttpClient 구현"을 "AndroidClientHandler"로 설정하십시오. 이 옵션은 프로젝트 옵션> Android 빌드> 코드 생성 및 런타임에서 찾을 수 있습니다. 안드로이드 5+

http implementation option

+0

당신은 단지 을 호출 할 수있다.'''var client = new HttpClient (new Xamarin.Android.Net.AndroidClientHandler()); 클라이언트 = 새로운 HttpClient (new Xamarin.Android.Net.AndroidClientHandler());''' 가 문제를 해결합니까? – kevskree

+0

코드를 포맷하십시오. https://meta.stackoverflow.com/questions/251361/how-do-i-format-my-code-blocks – IsuruAb

+0

예. 'getAsync()'또는'postAsync()'를 만드는 데 사용할 httpClient를 만들기 전에 두 개의 httpclient를 만듭니다. 또한 "HttpClient 구현"을 "AndroidClientHandler"로 설정하십시오. 이 옵션은 프로젝트 옵션> Android 빌드> 코드 생성 및 런타임에서 찾을 수 있습니다. –