MonoDroid:Encoding.ASCII.GetString失败

间歇性地,Encoding.ASCII.GetString调用失败,exception会转义所有catch块并冻结应用程序。

private string ExecuteRequest(Uri url, KeyValuePair[] 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"); } } 

StackTrace我得到的是

 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)  I/mono (10960): at System.Text.Encoding.GetString (byte[])  I/mono (10960): at ServiceRequest.ExecuteRequest (System.Uri,System.Collections.Generic.KeyValuePair`2[])  

间歇性地,我得到一个如下所示的不寻常的堆栈跟踪

 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 

响应是json数据,范围在1-4 MB之间。

请帮忙。 谢谢!!!!

编辑2 :我更新代码使用UploadString而不是UploadData,间歇性地得到这个:

 I/mono (15065): Stacktrace: I/mono (15065): I/mono (15065): at string.CreateString (char[])  I/mono (15065): at (wrapper managed-to-managed) string..ctor (char[])  I/mono (15065): at System.Text.Encoding.GetString (byte[],int,int)  I/mono (15065): at System.Text.UTF8Encoding.GetString (byte[],int,int)  I/mono (15065): at System.Text.Encoding.GetString (byte[])  I/mono (15065): at System.Net.WebClient.UploadString (System.Uri,string,string)  I/mono (15065): at (wrapper remoting-invoke-with-check) System.Net.WebClient.UploadString (System.Uri,string,string)  

首先,请填写一份错误报告,正如Rolf在评论中所说的那样。 第二个堆栈跟踪是永远不会发生的崩溃。

至于第一个问题,有没有理由不使用(其中一个重载) WebClient.UploadString ?

该方法将处理编码,确保HTTP请求头匹配,编码请求和响应…这也将返回一个字符串(更少的代码:-)。

否则你最终可能会得到一个字符串(除非你在此代码之前有其他validation),这些字符串不能用ASCII编码并且会导致exception(遗憾的是我们只有堆栈跟踪,而不是抛出确切的exception来确认这一点)。

在此处分页数据和下载可能是唯一正确且可扩展/可靠的解决方案。

现在,下面的代码没有爆炸,可能是我没有达到临界点。 但这是我第一次在设备上进行分块。 Encoding.ASCII.GetString在下面的代码中没有爆炸。

 private string ExecuteRequest(Uri url, KeyValuePair[] 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"); } }