OutOfMemoryException при выполнении запроса Http GETC#

Место общения программистов C#
Ответить
Anonymous
 OutOfMemoryException при выполнении запроса Http GET

Сообщение Anonymous »

Это простой сценарий: сделайте запрос и преобразуйте результат json в эквивалентный класс POCO.
Изначально я преобразовывал ответ в строку, а затем десериализовал его:
private async Task CallApiAsync(string url)
{
var httpResponseMessage = await _httpClient.GetAsync(url);
if (httpResponseMessage.IsSuccessStatusCode)
{
var responseBody = await httpResponseMessage.Content.ReadAsStringAsync(); // this one here
return Newtonsoft.Json.JsonConvert.DeserializeObject(responseBody);
}
var errors = await httpResponseMessage.Content.ReadAsStringAsync();
throw DomainError(httpResponseMessage.StatusCode, url, errors);
}

Раньше я получал эту периодически возникающую ошибку:
"Message": "Exception of type 'System.OutOfMemoryException' was thrown.",
"Source": "System.Private.CoreLib",
"StackTraceString": " at System.String.CreateStringFromEncoding(Byte* bytes, Int32 byteLength, Encoding encoding)
in /_/src/System.Private.CoreLib/shared/System/String.cs:line 505\n
at System.Text.UTF8Encoding.GetString(Byte[] bytes, Int32 index, Int32 count)
in /_/src/System.Private.CoreLib/shared/System/Text/UTF8Encoding.cs:line 663\n
at System.Net.Http.HttpContent.ReadBufferAsString(ArraySegment`1 buffer, HttpContentHeaders headers)
in /_/src/System.Net.Http/src/System/Net/Http/HttpContent.cs:line 223\n
at System.Net.Http.HttpContent.ReadBufferedContentAsString() in /_/src/System.Net.Http/src/System/Net/Http/HttpContent.cs:line 182\n
at System.Net.Http.HttpContent.WaitAndReturnAsync[TState,TResult](Task waitTask, TState state, Func`2 returnFunc)
in /_/src/System.Net.Http/src/System/Net/Http/HttpContent.cs:line 717\n
at Infrastructure.Clients.SecurityMasterFileService.CallApiAsync[T](String url)
in /app/Infrastructure/Clients/SecurityMasterFileService.cs:line 68\n

Поэтому я перешел на чтение из потока, поскольку не было смысла конвертировать в строку и перегружать память:
private async Task CallApiAsync(string url)
{
using var httpResponseMessage = await _httpClient.GetAsync(url); //added "using"
if (httpResponseMessage.IsSuccessStatusCode)
{
using var responseBody = await httpResponseMessage.Content.ReadAsStreamAsync(); //changed this line
return await System.Text.Json.JsonSerializer.DeserializeAsync(responseBody); //also changed from Newtonsoft to System.Text since the former did not have async overload
}
var errors = await httpResponseMessage.Content.ReadAsStringAsync();
throw DomainError(httpResponseMessage.StatusCode, url, errors);
}

Теперь я получаю периодически возникающую ошибку:
"Message": "Exception of type 'System.OutOfMemoryException' was thrown.",
"Source": "System.Private.CoreLib",
"StackTraceString": " at System.IO.MemoryStream..ctor(Int32 capacity)
in /_/src/System.Private.CoreLib/shared/System/IO/MemoryStream.cs:line 47\n
at System.Net.Http.HttpContent.CreateMemoryStream(Int64 maxBufferSize, Exception& error)
in /_/src/System.Net.Http/src/System/Net/Http/HttpContent.cs:line 522\n
at System.Net.Http.HttpContent.LoadIntoBufferAsync(Int64 maxBufferSize, CancellationToken cancellationToken)
in /_/src/System.Net.Http/src/System/Net/Http/HttpContent.cs:line 430\n
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
in /_/src/System.Net.Http/src/System/Net/Http/HttpClient.cs:line 546\n
at Infrastructure.Clients.SecurityMasterFileService.CallApiAsync[T](String url) in /app/Infrastructure/Clients/SecurityMasterFileService.cs:line 68\n

Итак, теперь мне интересно, что еще нужно исправить в новой реализации. Может кто-нибудь указать мне в правильном направлении. Спасибо.
Изменить: добавление полезных данных json: https://jsonblob.com/4d2eac0f-f42a-11eb ... Примечание. Из полезных данных json мне нужны только первые два объекта, поэтому для первых двух у меня есть класс POCO:
public class Root
{
public RootA RootA { get; set; }
public RootB RootB { get; set; }
}
public class RootA
{
public string Field1 { get; set; }
public string Field2 { get; set; }
public int Field3 { get; set; }
public string Field4 { get; set; }
public string Field5 { get; set; }
public int Field6 { get; set; }
public int Field7 { get; set; }
public string Field8 { get; set; }
public string Field9 { get; set; }
public int Field10 { get; set; }
public int Field11 { get; set; }
public int Field12 { get; set; }
public int Field13 { get; set; }
public DateTime Field14 { get; set; }
public string Field15 { get; set; }
public DateTime Field16 { get; set; }
public string Field17 { get; set; }
public string Field18 { get; set; }
public string Field19 { get; set; }
public string Field20 { get; set; }
public string Field21 { get; set; }
public string Field22 { get; set; }
public string Field23 { get; set; }
public string Field24 { get; set; }
public string Field25 { get; set; }
public string Field26 { get; set; }
public DateTime Field27 { get; set; }
}

public class RootB
{
public string Field1 { get; set; }
public string Field2 { get; set; }
public DateTime Field3 { get; set; }
public string Field4 { get; set; }
public string Field5 { get; set; }
public string Field6 { get; set; }
public string Field7 { get; set; }
public string Field8 { get; set; }
public int Field9 { get; set; }
public int Field10 { get; set; }
public int Field11 { get; set; }
public int Field12 { get; set; }
public int Field13 { get; set; }
public string Field14 { get; set; }
public int Field15 { get; set; }
public int Field16 { get; set; }
public int Field17 { get; set; }
public int Field18 { get; set; }
public int Field19 { get; set; }
public int Field20 { get; set; }
public int Field21 { get; set; }
public string Field22 { get; set; }
public int Field23 { get; set; }
public string Field24 { get; set; }
public int Field25 { get; set; }
public int Field26 { get; set; }
public string Field27 { get; set; }
public int Field28 { get; set; }
public int Field29 { get; set; }
public string Field30 { get; set; }
public int Field31 { get; set; }
public string Field32 { get; set; }
public string Field33 { get; set; }
public string Field34 { get; set; }
public string Field35 { get; set; }
public string Field36 { get; set; }
public string Field37 { get; set; }
public int Field38 { get; set; }
public string Field39 { get; set; }
public int Field40 { get; set; }
public string Field41 { get; set; }
public DateTime Field42 { get; set; }
public DateTime Field43 { get; set; }
public DateTime Field44 { get; set; }
public string Field45 { get; set; }
public DateTime Field46 { get; set; }
public DateTime Field47 { get; set; }
public string Field48 { get; set; }
public int Field49 { get; set; }
public string Field50 { get; set; }
public string Field51 { get; set; }
public DateTime Field52 { get; set; }
public string Field53 { get; set; }
public string Field54 { get; set; }
public string Field55 { get; set; }
public int Field56 { get; set; }
public string Field57 { get; set; }
public string Field58 { get; set; }
public string Field59 { get; set; }
public string Field60 { get; set; }
public string Field61 { get; set; }
public DateTime Field62 { get; set; }
public string Field63 { get; set; }
public int Field64 { get; set; }
public string Field65 { get; set; }
public string Field66 { get; set; }
}



Подробнее здесь: https://stackoverflow.com/questions/686 ... et-request
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»