TGViewer
C# (C Sharp) programming C# (C Sharp) programming @csharp_ci · 18.1K subscribers
Post #779 5.75K
🖥 Как можно реализовать ограничение на одновременное скачивание файлов?

▶️Итак, есть сервис, который отдает пользователям видео файлы, реализован метод для скачивания файла, который отдает файл через метод File:
[HttpGet("file/{guid}/download")]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<IActionResult> DownloadFile([FromRoute] Guid guid)
{
var file = await _mediaContentService.DownloadFile(guid);

return File(file.Stream, file.ContentType, file.FileName);
}

Можно ли каким-либо образом реализовать ограничение на скачивание файла, чтобы, например, в единицу времени не больше N пользователей качало файл?


▶️Проблема с методом File — он возвращает ленивый ответ. Т.е. он не читает весь поток сразу, а ждет пока будет вызван метод от IActionResult.
Чтобы эту проблему решить, надо знать, когда файл точно отправлен.
Можно сделать специальный декоратор. Например:
[ApiController]
[Route("[controller]")]
public class SampleController : ControllerBase
{
private readonly IRateLimiter _rateLimiter;

public SampleController(IRateLimiter rateLimiter)
{
_rateLimiter = rateLimiter;
}

[HttpGet("connection")]
public async Task<IActionResult> DownLoadFile(Guid file)
{
var stream = await GetFileStream(file);
return new RateLimiterFileActionResult(File(stream, "content/type", "sample.txt"), _rateLimiter);
}
}

class RateLimiterFileActionResult : IActionResult
{
private readonly IActionResult _actionResultImplementation;
private readonly IRateLimiter _rateLimiter;

public RateLimiterFileActionResult(IActionResult actionResultImplementation, IRateLimiter rateLimiter)
{
_actionResultImplementation = actionResultImplementation;
_rateLimiter = rateLimiter;
}

public async Task ExecuteResultAsync(ActionContext context)
{
try
{
await _rateLimiter.ObtainAsync(context.HttpContext.RequestAborted);
await _actionResultImplementation.ExecuteResultAsync(context);
}
finally
{
await _rateLimiter.ReleaseAsync(context.HttpContext.RequestAborted);
}
}
}

public interface IRateLimiter
{
public Task ObtainAsync(CancellationToken token);
public Task ReleaseAsync(CancellationToken token);
}

Стоит заметить, что блокировка берётся внутри метода декоратора, а не в методе контроллера.

@csharp_ci
More from @csharp_ci
  1. Oct 14, 2026Альфа-Банк ищет скиллового коллегу QA Fullstack на C# Предлагаем полную удалёнку или гибри…
  2. Oct 13, 2026🧱 Модульный монолит легко потерять одним удобным JOIN. Допустим, модуль заказов напрямую…
  3. Oct 11, 2026Задачка по C# 14: обновили проект на .NET 10, и код молча начал работать иначе Что выведет…
  4. Oct 9, 2026Post #1901
  5. Oct 7, 2026⚡️ Microsoft переработала C# Dev Kit: меньше памяти, быстрее запуск В версии 11.0 шесть пр…
  6. Oct 6, 2026🛠 Вышел Microsoft.Data.SqlClient 7.1.1 Обновление .NET-драйвера для SQL Server исправляет…
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 →