间歇性地,Encoding.ASCII.GetString调用失败,异常会转义所有catch块并冻结应用程序。
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");
}
}
我得到的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) <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
响应是json数据,范围在1-4 MB之间。
请帮忙。感谢!!!!
编辑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>
答案 0 :(得分:0)
首先,请填写一份错误报告,正如Rolf在评论中所说的那样。第二个堆栈跟踪是一个永远不会发生的崩溃。
关于第一个问题,有没有理由不使用(其中一个重载)WebClient.UploadString?
该方法将处理编码,确保HTTP请求头匹配,编码请求和响应...这也将返回一个字符串(代码较少的代码:-)。
否则你最终可能会得到一个字符串(除非你在此代码之前有其他验证),这些字符串不能用ASCII编码并且会导致异常(遗憾的是我们只有堆栈跟踪,而不是抛出的确切异常来确认这一点)。
答案 1 :(得分: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");
}
}