2011-11-21 38 views
1

Intermittently,Encoding.ASCII.GetString調用失敗,出現一個異常,該異常將所有catch塊凍結並凍結應用程序。MonoDroid:Encoding.ASCII.GetString失敗

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"); 
    }    
} 

堆棧跟蹤我得到的是

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> 

Intermitently,我得到下面

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 

的響應示出的不同尋常堆棧跟蹤是可以爲1之間JSON數據 - MB 4。

請幫忙。謝謝!!!!

編輯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條記錄。 –