2011-11-21 4 views
1

간헐적으로 Encoding.ASCII.GetString 호출이 실패하고 모든 catch 블록을 이스케이프 처리하여 응용 프로그램을 고정시킵니다. 4메가바이트 - 내가 얻을MonoDroid : Encoding.ASCII.GetString failing

private string ExecuteRequest(Uri url, KeyValuePair<string, string>[] postItems = null) 
{ 
    var data = new byte[0]; 
    var response = new byte[0]; 
    using (var client = new WebClient()) 
    { 
     if (postItems != null && postItems.Count() > 0) 
     { 
      string dataString = string.Join("&", postItems.Select(
            item => string.Format("{0}={1}", item.Key, item.Value)).ToArray()); 
      data = new ASCIIEncoding().GetBytes(dataString); 
     } 
     response = client.UploadData(url, "POST", data); 
     Android.Util.Log.Info("info", "response from the post received. about to get string"); 
     client.Dispose(); 
    } 
    try 
    { 
     return Encoding.ASCII.GetString(response); 
    } 
    catch (Exception ex) 
    { 
     Android.Util.Log.Info("info", 
      "Encoding.ASCII.GetString Exception : {0}, {1}", ex.Message, ex.StackTrace); 
     throw new ApplicationException("UnRecoverable. Abort"); 
    }    
} 

스택 트레이스 1 사이의 범위 수 JSON 데이터가 내가

I/mono (9817): Stacktrace: 
I/mono (9817): 
F/  (9817): * Assertion at ../../../../mono/mini/mini-exceptions.c:472, condition `class' not met 
D/dalvikvm( 220): GC_EXPLICIT freed 1K, 35% free 17547K/26759K, paused 3ms+3ms 

응답 아래에 나타낸 대한 unusal 스택 트레이스를 얻고,이 intermitently

I/sssvida (10960): response from the post received. about to get string 
I/mono (10960): Stacktrace: 
I/mono (10960): 
I/mono (10960): at System.Text.ASCIIEncoding.GetString (byte[],int,int) <0x000cb> 
I/mono (10960): at System.Text.Encoding.GetString (byte[]) <0x00037> 
I/mono (10960): at ServiceRequest.ExecuteRequest (System.Uri,System.Collections.Generic.KeyValuePair`2<string, string>[]) <0x0026b> 

입니다.

도와주세요. 감사!!!!

편집 2 : 나는 UploadString 대신 UploadData를 사용하도록 코드를 업데이트하고 간헐적으로 나는이 얻을 : 롤프는 의견 요청으로

I/mono (15065): Stacktrace: 
I/mono (15065): 
I/mono (15065): at string.CreateString (char[]) <0x0004b> 
I/mono (15065): at (wrapper managed-to-managed) string..ctor (char[]) <0xffffffff> 
I/mono (15065): at System.Text.Encoding.GetString (byte[],int,int) <0x00043> 
I/mono (15065): at System.Text.UTF8Encoding.GetString (byte[],int,int) <0x0002b> 
I/mono (15065): at System.Text.Encoding.GetString (byte[]) <0x00037> 
I/mono (15065): at System.Net.WebClient.UploadString (System.Uri,string,string) <0x0007f> 
I/mono (15065): at (wrapper remoting-invoke-with-check) System.Net.WebClient.UploadString (System.Uri,string,string) <0xffffffff> 
+1

이것은 분명히 버그입니다. 재현 가능한 테스트 케이스로 http://bugzilla.xamarin.com에 버그를 제출하십시오. –

답변

0

페이지 데이터 및 청크 다운로드는 여기에서 유일하고 정확하고 확장 가능하며 강력한 솔루션 일 수 있습니다.

지금 아래 코드는 불어 나지 않고 있습니다. 팁을 맞추지 않았을 수도 있습니다. 그러나 이것은 장치에서 청킹에 대한 첫 번째 단계입니다. Encoding.ASCII.GetString은 아래 코드에서 폭발하지 않습니다.

private string ExecuteRequest(Uri url, KeyValuePair<string, string>[] postItems = null) 
{ 
    var data = new byte[0]; 
    var response = new byte[0]; 
    ///switched to WebClient because 
    /// http://stackoverflow.com/questions/8167726/monodroid-intermittent-failure-when-reading-a-large-json-string-from-web-servi 
    using (var client = new WebClient()) 
    { 
     if (postItems != null && postItems.Count() > 0) 
     { 
      string dataString = string.Join("&", postItems.Select(
            item => string.Format("{0}={1}", item.Key, item.Value)).ToArray()); 
      data = new ASCIIEncoding().GetBytes(dataString); 
     } 
     response = client.UploadData(url, "POST", data); 
     Android.Util.Log.Info("info", "response from the post received. about to get string"); 
     client.Dispose(); 
    } 
    try 
    { 
     Android.Util.Log.Info("info", "response size : {0}", response.Length); 
     var chunkSize = 50000; 
     if (response.Length > chunkSize) 
     { 
      var returnValue = new StringBuilder(); 
      for (int i = 0; i < response.Length; i+= chunkSize) 
      {       
       int end = (i + chunkSize) > response.Length ? response.Length - i : chunkSize; 
       returnValue.Append(Encoding.ASCII.GetString(response, i, end)); 
       Android.Util.Log.Info("info", "added a chunk from {0} to {1}", i, end); 
      } 
      return returnValue.ToString(); 
     } 
     return Encoding.ASCII.GetString(response); 
    } 
    catch (Exception ex) 
    { 
     Android.Util.Log.Info("info", 
      "Encoding.ASCII.GetString Exception : {0}, {1}", ex.Message, ex.StackTrace); 
     throw new ApplicationException("UnRecoverable. Abort"); 
    }    
} 
0

첫째, 버그 리포트를 작성하십시오. 두 번째 스택 추적은 결코 발생해서는 안되는 충돌입니다.

첫 번째 문제는 사용하지 않는 이유가 있습니까 (과부하 중 하나임) WebClient.UploadString?

그 방법은 인코딩과 HTTP 요청 헤더 일치, 요청 및 응답 인코딩 ... 또한 당신에게 문자열을 돌려 줄 것입니다 (당신을위한 적은 코드 :-).

그렇지 않으면 ASCII로 인코딩 할 수없고 예외를 유발할 수있는 문자열로 끝날 수 있습니다 (슬프게도 우리는 스택 추적 만 있고 정확한 예외는 발생하지 않습니다). 이것을 확인하십시오).

+0

poupou, 답장을 보내 주셔서 감사합니다. 나는 처음에는 문자열 실제가 반환 형식을 참조하는 메서드 이름으로 혼란스러워했습니다. 질문에서 '편집'을 참조하십시오. 동기화하는 동안 약 10 개의 테이블을 가져오고, 동기화를 반복하면 위의 예외가 간헐적으로 발생합니다. –

+0

이제 데이터를 다운로드하기 위해 페이징/청킹을 사용할 생각입니다. sysnc가 작동해야하므로 한 번에 약 50 개의 레코드를 다운로드 할 것이라고 생각합니다. –