#c# #xamarin #xamarin.forms #aws-lambda #streamwriter.write
Вопрос:
У меня есть приложение xamarin forms, которое выполняет вызовы API, и когда вызовы api включают очень маленькие строки json, они работают идеально. Примером полезной нагрузки, которая работает, является:
{"command":"","route":"check_password","password":"password","sqlctype":"","service":"",data:""}
Примером полезной нагрузки, которая не работает, является:
{"command":"","route":"run_script","password":"","sqlctype":"","service":"Image_Processor",data:"base64 string that is 2MB in size"}
Однако со второй полезной нагрузкой StreamWriter не успевает ее записать и зависает на неопределенный срок. Мой код здесь:
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{"command":"","
""route":"" route "","
""password":"" password "","
""sqlctype":"","
""service":"" service "","
""data":"" data ""}";
streamWriter.Write(json);
}
Но самое интересное заключается в том, что операция API успешно завершается в обоих случаях
Журналы cloudwatch для запуска с первой полезной нагрузкой выглядят следующим образом:
START RequestId: ee583521-f17d-4143-9c27-031ab781ddae Version: $LATEST
END RequestId: ee583521-f17d-4143-9c27-031ab781ddae
REPORT RequestId: ee583521-f17d-4143-9c27-031ab781ddae Duration: 7.01 ms Billed Duration: 8 ms Memory Size: 128 MB Max Memory Used: 93 MB XRAY TraceId: 1-611ac895-4ba33ffa6e181b6e66821bfc...
С возвращенным телом
"T"
Журналы cloudwatch для запуска со второй полезной нагрузкой выглядят следующим образом:
START RequestId: d78b16de-1a0b-4b35-877a-2fd6437dcd71 Version: $LATEST
END RequestId: d78b16de-1a0b-4b35-877a-2fd6437dcd71
REPORT RequestId: d78b16de-1a0b-4b35-877a-2fd6437dcd71 Duration: 4159.55 ms Billed Duration: 4160 ms Memory Size: 128 MB Max Memory Used: 93 MB XRAY TraceId: 1-611ac940-61cca9b762d1a2ff6...
С возвращенным телом
"[{"typ": "barcode", "outp": "0882658000546", "ymax": "0.6736111111111112", "ymin": "0.550843253968254", "xmax": "0.6736111111111112", "xmin": "0.3488756613756614"}, {"typ": "barcode", "outp": "A-0020-Z", "ymax": "0.4595734126984127", "ymin": "0.40153769841269843", "xmax": "0.6008597883597884", "xmin": "0.3194444444444444"}, {"typ": "barcode", "outp": "A-0010-Z", "ymax": "0.34077380952380953", "ymin": "0.29092261904761907", "xmax": "0.5929232804232805", "xmin": "0.328042328042328"}]"
Поскольку API явно работает и успешно работает в обоих случаях, почему приложение может зависать на
streamWriter.Write(json)
имея только вторую полезную нагрузку?
Также может быть полезно отметить, что я тоже пытался сделать это асинхронно, и это зависало на клиенте.postasync независимо от полезной нагрузки (ни одна полезная нагрузка не зависала). Код:
async Task<string> asyncAPI(string route, string password = "", string data = "", string service = "")
{
HttpClient client = new HttpClient();
Uri uri = new Uri("https://uidvxrcio9.execute-api.us-east-2.amazonaws.com/default/Blueline_General_API");
string json = JsonConvert.SerializeObject(new APIrequest(default, route, password, default, service, "dawdasdqwd2"));
StringContent content = new StringContent(json, Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Add("x-api-key", "key");
HttpResponseMessage response = null;
response = await client.PostAsync(uri, content);
return await response.Content.ReadAsStringAsync();
}
Комментарии:
1. Декодирование base64 такого размера по своей природе связано с ЦП. Мобильные телефоны имеют очень символический процессор. Так что на самом деле это может быть то, сколько времени это займет. Вы пробовали некоторые промежуточные размеры данных, которые больше 0, но меньше 2 Мбайт?
2. Декодирование не выполняется по телефону. Кодирование выполнено, а затем полученная строка base64 записывается в поток запросов HttpWebRequest и отправляется в API.
3. @OwenBurns «зависает на неопределенный срок» ? Выполняется ли эта работа в потоке, не относящемся к пользовательскому интерфейсу? Убивает ли ОС приложение через ANR? Каково текущее состояние процесса? Что там внутри
logcat
?4. 2 МБ-это немного. Проблема почти наверняка не в потоковом писателе. В качестве теста сначала прочитайте поток запросов в строку в памяти. Держу пари, что именно это и висит. Что еще более важно, сделайте это в фоновом потоке — веб-ответ, должно быть, занял слишком много времени, вызвал некоторые проблемы в основном потоке. Вы искали в выводе отладки предупреждения или ошибки?
5. В окне отладки нет ничего, кроме потоков, которые открываются и затем закрываются. Я не уверен, как проверить статус процесса, и я не уверен, что означает ANR. Он выполняется в блокирующем потоке. Я добавил вывод logcat к вопросу.
Ответ №1:
Почему вы пытаетесь сериализовать свой собственный код? Используйте Newtonsoft.Пакет Json nuget и используйте методы, описанные в нем. Когда вы устанавливаете их, вы можете легко сериализовать все общедоступные свойства класса. Код для сериализации одного из ваших классов выглядит следующим образом:
JsonConvert.SerializeObject(myCompany)
Если вы пытаетесь сериализовать необработанные данные….вы можете создать свойство byte[] в своем классе, например:
public byte[] MyBytes {get; set;}
Комментарии:
1. хотя это хороший момент, он не должен иметь никакого отношения к тому, отказывает или нет
StreamWriter.Write()
2. Возможно….но является ли этот раздел текста выше допустимым json? ,данные:»строка base64 размером 2 МБ»} В поле данных нет кавычек….
3. Я использую плагин просмотра json в Notepad , и он не будет форматировать этот текст в формате json: {«команда»:»»,»маршрут»:»run_script»,»пароль»:»»,»тип sqlc»:»»,»служба»:»Обработчик изображений», данные: «строка base64 размером 2 МБ»} В нем говорится, что json недействителен.
4. Я не уверен, как JSON может быть недействительным, когда небольшие запросы работают должным образом. Не будет ли неправильный JSON означать, что код вообще не будет работать?
5. Я попробовал это сейчас, и это не решило мою проблему.