MonoDroid: ошибка Encoding.ASCII.GetString - PullRequest
1 голос
/ 21 ноября 2011

Периодически происходит сбой вызова 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>

Периодически я получаю необычную трассировку стека, показанную ниже

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 мб.

Пожалуйста, помогите.Спасибо !!!!

Редактировать 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>

Ответы [ 2 ]

0 голосов
/ 22 ноября 2011

Пейджинговые данные и загрузка в блоках могут быть единственным правильным и масштабируемым / надежным решением здесь.

На данный момент приведенный ниже код не взрывается, возможно, я не достиг переломного момента.Но это мой первый проход на устройстве.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 голосов
/ 22 ноября 2011

Во-первых, пожалуйста, заполните сообщение об ошибке, как спросил Рольф в комментариях.Вторая трассировка стека - это сбой, который никогда не должен происходить.

Что касается первой проблемы, есть ли причина не использовать (одна из перегрузок) WebClient.UploadString ?

Этот метод будет заботиться о кодировке, обеспечивая совпадение заголовка HTTP-запроса, кодируя запрос и ответ ... который также вернет вам строку (меньше кода для вас :-).

В противном случае вы можете получить строку (если у вас нет других проверок до этого кода), которая не может быть закодирована в ASCII и которая вызовет исключения (к сожалению, у нас есть только трассировка стека, а не точное исключениеброшен, чтобы подтвердить это).

...