1

断続的に、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");
    }            
}

私が得る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>

断続的に、以下に示す異常なスタックトレースを取得しています

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〜4mbの範囲のjsonデータです。

助けてください。ありがとう!!!!

編集2:UploadDataの代わりにUploadStringを使用するようにコードを更新しましたが、断続的に次のようになります:

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>
4

2 に答える 2

0

まず、Rolfがコメントで尋ねたように、バグレポートに記入してください。2番目のスタックトレースは、発生してはならないクラッシュです。

最初の問題に関しては、(オーバーロードの1つである) WebClient.UploadStringを使用しない理由はありますか?

このメソッドはエンコードを処理し、HTTPリクエストヘッダーが一致することを確認し、リクエストとレスポンスをエンコードします...これにより文字列も返されます(コードが少なくなります:-)。

そうしないと、ASCIIでエンコードできず、例外が発生する文字列(このコードの前に他の検証がない限り)が発生する可能性があります(残念ながら、これを確認するためにスローされる正確な例外ではなく、スタックトレースしかありません)。

于 2011-11-21T20:27:52.173 に答える
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");
    }            
}
于 2011-11-21T22:05:14.743 に答える