.Net 7 httpclient, httpresponsemessage.content.readassstreamasync - Проблемы с памятьюC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 .Net 7 httpclient, httpresponsemessage.content.readassstreamasync - Проблемы с памятью

Сообщение Anonymous »

Среда-это сервис .net (.net7.0), работающий в контейнере Docker на основе Linux. Он должен общаться с внешним API REST, загрузить файл с застежкой с большим настройкой, распаковать его и загружать в хранилище Blob-Blob. services.AddHttpClient()
.ConfigurePrimaryHttpMessageHandler(createHttpMessageHandler);
< /code>
на фабрике, которая называется потребителем со следующим обработчиком: < /p>
services.AddMyApiClientFactory(() =>
{
var handler = new SocketsHttpHandler()
{
SslOptions =
{
RemoteCertificateValidationCallback = (_, _, _, _) => true
},
PooledConnectionLifetime = TimeSpan.FromMinutes(1),
PooledConnectionIdleTimeout = TimeSpan.FromSeconds(30),
MaxConnectionsPerServer = 3
};
return handler;
});
< /code>
Проверка сертификата обходится по причинам, а параметры объединенных соединений предлагаются CHATGPT (как и я, нельзя сказать).
MyhttpClient создается вместе с клиентом API, а клиент API создается один раз в цикл SERVIC Этот механизм: < /p>
public async Task GetFilesAsStreamAsync(GetFilesRequest request, CancellationToken cancellationToken = default)
{
string query = String.Empty
.AddParameter(request, x => x.Path)
.AddParameter(request, x => x.FileList); // doesn't matter - just makes a correct query

var requestMessage = new HttpRequestMessage(HttpMethod.Get, "download?" + query);
requestMessage.Headers.ConnectionClose = true;
HttpResponseMessage response = await _httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
response.EnsureSuccessStatusCode();
var stream = await response.Content.ReadAsStreamAsync(cancellationToken);
return new HttpContentStreamWrapper(stream, response);
}
< /code>
httpcontentstreamwrapper существует, чтобы позволить потребителю избавиться от ответа вместе с полученным потоком. Он имеет эту логику, иначе это просто фасад для потока: < /p>
protected override void Dispose(bool disposing)
{
if (disposing)
{
_innerStream.Dispose();
_response.Dispose();
}
base.Dispose(disposing);
}

public override async ValueTask DisposeAsync()
{
await _innerStream.DisposeAsync();
_response.Dispose();
await base.DisposeAsync();
}
< /code>
Наконец, потребитель делает следующее, когда пришло время загрузить файл и сделать что -то с ним (вся ведение журнала и телеметрия раздетаются, надеясь, что вся логика остается): < /p>
using (var zippedDataStream = await myApiClient.GetFilesAsStreamAsync(request))
{
using (var zip = new ZipArchive(zippedDataStream))
{
var zipEntry = zip.Entries.FirstOrDefault();
using (var entryStream = zip.Entries.First().Open())
{

var storageClient = _blobContainerClient.GetBlobClient(pathInStorage(baseUrl, fileName));
await storageClient.UploadAsync(entryStream, overwrite: true);
}
}
}
< /code>
Код выше приведен в асинхронном методе, который называется 3 раза параллельно, и все задачи ожидаются (есть и вещи, которые случаются, когда конкретный файл закончит загрузку, но кажется, что все асинхронные трюки работают хорошо, все правильно ожидается и т. Д. Content.ReadAssTreamAsync (), позже будет утилизироваться вызывающим абонент - как поток, так и ответ. Мой главный вопрос: есть ли в этом коде ошибки обработки памяти? Первоначально я явно не избавлялся от потока, и предположительно, хотя он был в конечном итоге утилизировал логику на основе объема, связанный объект ответа не был. И, кроме того, HTTPClient был настроен с другим (более старым) обработчиком, который, опять же, по словам CHATGPT, не был хорошим. Таким образом, у нас просто закончится память относительно быстро, пролившись в Swapfile, также закончилась из этого и в конечном итоге вызывает неприятности. Теперь, кажется, лучше, однако, я не понимаю пару вещей. Если я явно вызовут GC после того, как каждый файл готов загрузить, то на самом деле он немного хорош: после сначала загрузку память поднимается, но тогда она просто остается там, очевидно, некоторые буферы создаются и используются повторными внутренними ресурсами HTTPClient -? - понятия не имею ... но я думаю, что запуск GC явно не кошерный, а если я этого не сделаю, память, кажется, поднимается до предела контейнера, а затем остается там, поэтому я предполагаю, что GC делает достаточно, чтобы снять давление, но не больше, чем это. Я мог бы жить с этим. Я вернулся к двум экземплярам контейнера, каждый из которых использовал менее 10% памяти (Yay!), Но каждый также использует большие куски файла свопа хоста, которого я не получаю, если честно. Я делаю что -то принципиально не так с тем, как я делаю утилизацию объектов? Есть ли способ переписать загрузку таким образом, что ей не нужно так много памяти? Может быть, проблема с распадкой поток? Должен ли я загрузить файл на диск и позволить библиотеке ZIP работать оттуда? Любой вход ценится!

Подробнее здесь: https://stackoverflow.com/questions/796 ... ory-troubl
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • .net httpclient, httpresponsemessage.content.readassstreamasync - Проблема с памятью
    Anonymous » » в форуме C#
    0 Ответы
    5 Просмотры
    Последнее сообщение Anonymous
  • .Net 7 httpclient, httpresponsemessage.content.readassstreamasync - Проблемы с памятью
    Anonymous » » в форуме C#
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous
  • .Net 7 httpclient, httpresponsemessage.content.readassstreamasync - Проблемы с памятью
    Anonymous » » в форуме C#
    0 Ответы
    2 Просмотры
    Последнее сообщение Anonymous
  • Загрузите PDF/изображение/любой файл в ASP.NET Core 8, где файл поступает из HttpResponseMessage.Content веб-API.
    Anonymous » » в форуме C#
    0 Ответы
    54 Просмотры
    Последнее сообщение Anonymous
  • Как показать изображение в HttpResponseMessage.Content.Headers.ContentType
    Anonymous » » в форуме C#
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous

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