TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2371 2.65K
День 1961. #ЗаметкиНаПолях
Ожидает ли HttpClient всё Тело Ответа?
Если вы вызываете HttpClient.GetAsync или HttpClient.PostAsync, а затем ожидаете результат, ожидается получение только заголовков или всего тела ответа?

Сервер
Создадим простой сервер, который отправляет ответ с заголовком и телом. Тело будет отправляться частями, чтобы мы могли видеть, когда оно будет получено.
app.MapGet("/", async ctx =>
{
await ctx.Response.WriteAsync("1");
await Task.Delay(500);
await ctx.Response.WriteAsync("2");
await Task.Delay(500);
await ctx.Response.WriteAsync("3");
await ctx.Response.CompleteAsync();
});

Таким образом, весь запрос занимает не менее 1 секунды. Напишем простой вызов этой конечной точки.

Клиент
using var client = new HttpClient();

// измерим время до получения ответа
var sw = Stopwatch.StartNew();
await client.GetAsync("https://localhost:5001");
Console.WriteLine(
$"Время отклика: {sw.ElapsedMilliseconds}мс");

Если выполнить этот код, мы увидим, что время ответа составляет около 1 секунды. Таким образом, await ожидает получения всего тела:
Время отклика: 1088мс

Теперь посмотрим, как можно не ждать тела. Используем опцию HttpCompletionOption.ResponseHeadersRead:
var sw = Stopwatch.StartNew();
await client.GetAsync("https://localhost:5001",
HttpCompletionOption.ResponseHeadersRead);
Console.WriteLine(
$"Время отклика: {sw.ElapsedMilliseconds}мс");

Мы добавили флаг в вызов GetAsync. Теперь время отклика значительно меньше:
Время отклика: 78мс

Таким образом await ожидает только получения заголовков, и вы можете исследовать их сразу, как они будут получены. Тело всё ещё принимается в фоновом режиме. Если вы хотите дождаться получения тела, можно использовать метод ReadAsStringAsync:
using var response = 
await client.GetAsync("https://localhost:5001",
HttpCompletionOption.ResponseHeadersRead);
var body = await response.Content.ReadAsStringAsync();

Важно! Мы здесь используем using var response. Объект response продолжит удерживать ресурсы после await, поэтому необходимо удалять его как можно скорее.

Итого
Использование HttpCompletionOption.ResponseHeadersRead даёт выигрыш в производительности и памяти, и вы всё равно можете прочитать тело, если захотите. Но будьте осторожны с объектом ответа, так как он может по-прежнему удерживать ресурсы, что усложняет код. Так что это не должно быть выбором по умолчанию, если в этом нет необходимости.

Источник: https://steven-giesel.com/blogPost/e2c3bcba-4f81-42b0-9b25-060da5e819fa/does-an-httpclient-await-the-header-and-the-body
  • 👍 38
More from @netdeveloperdiary
  1. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  2. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  3. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  4. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  5. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  6. Oct 3, 2026Post #3360
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →