Коротко — «бесконечный» ответ от Swagger (точнее: от сервера, когда вы делаете запрос через Swagger UI) означает, что обработчик запроса на сервере не завершил формирование/отправку ответа. Swagger тут ни при чём — он просто ждёт, пока сервер закроет ответ.
Ниже — самые частые причины и как их диагностировать/устранить.
1) Метод никогда не возвращает/ожидает незавершённый Task
- Пример проблемного кода:
- TaskCompletionSource остаётся не установлена;
- await какого‑то Task, который никогда не завершается.
- Что сделать: проверьте, не ждёте ли вы Task, который не завершится. Добавьте логирование начала/конца метода.
2) Асинхронный метод объявлен как async void
- async void нельзя использовать для контроллеров — ошибки/завершение не контролируются.
- Правильно: Task<IActionResult> или Task.
3) Блокировка через .Result / .Wait() (deadlock)
- Реже в ASP.NET Core, но всё же: если вы делаете sync-блокировку на асинхронном коде, в некоторых случаях это может привести к зависанию.
- Решение: всегда await вместо .Result/.Wait().
4) Вы сознательно стримите ответ (SSE, поток JSON, IAsyncEnumerable и т.п.)
- Если вы используете цикл, File/StreamResult, Response.WriteAsync в вечном цикле — это ожидаемое поведение: ответ «открыт» и не закрывается.
- Решение: если нужно одноразовый ответ — завершите поток; если нужен стрим — учитывайте, что Swagger UI/браузер будет держать соединение открытым.
5) Отсутствие return / неверная сигнатура метода
- Например, метод void без return, или вы забыли return Ok(model).
- Проверьте сигнатуру и тело метода.
6) Внешний вызов/зависимость не отвечает
- Ваш контроллер ждёт ответа от БД, HTTP‑сервиса и т.д. — и тот «завис».
- Диагностика: проверьте логи/таймауты у HttpClient/DB, добавьте таймауты и обработку CancellationToken (HttpContext.RequestAborted).
7) Неправильные заголовки/контент (реже)
- Например, сервер не отправил Content-Length и не закрывает соединение, а использует chunked; клиент ждёт больше данных. Но обычно браузер всё равно отображает то, что пришло; «вечный» ответ — обычно сервер не завершил.
Как диагностировать быстро
- Сделайте тот же запрос не через Swagger UI, а через curl/Postman — поведение такое же?
- Посмотрите логи приложения (включите уровень Debug), поставьте точки логирования в начале и конце действия.
- В Network (DevTools) посмотрите, приходят ли какие‑то байты (streaming) или просто статус Pending.
- Если подозреваете deadlock — запустите в отладчике и поставьте breakpoint в методе, посмотрите, где он «зависает».
Примеры исправлений
- Неправильно:
public async Task<IActionResult> Get() {
var tcs = new TaskCompletionSource<int>();
await tcs.Task; // никогда не set
return Ok();
}
Исправление: убрать tcs или установить его, или завершать по таймауту/CancellationToken.
- Неправильно:
public IActionResult Get() {
var result = SomeAsync().Result; // потенциальная блокировка
return Ok(result);
}
Правильно:
public async Task<IActionResult> Get() {
var result = await SomeAsync();
return Ok(result);
}
Если хотите — пришлите полный код метода контроллера (с атрибутами, сигнатурой и телом) — посмотрю конкретно и укажу, что в нём может приводить к «бесконечному» ответу.