ru
Feedback
C# (C Sharp) programming

C# (C Sharp) programming

Открыть в Telegram

📈 Аналитический обзор Telegram-канала C# (C Sharp) programming

Канал C# (C Sharp) programming (@csharp_ci) языкового сегмента Русский является активным участником. Сейчас сообщество объединяет 18 308 подписчиков, занимая 7 330 место в категории Технологии и приложения и 36 862 место в регионе Россия.

📊 Показатели аудитории и динамика

С момента создания невідомо проект демонстрирует стремительный рост, собрав аудиторию из 18 308 подписчиков.

Согласно последним данным от 13 июня, 2026, канал показывает стабильную активность. За последние 30 дней изменение числа участников составило -3, а за последние 24 часа — 7, при этом общий охват остаётся высоким.

  • Статус верификации: Не верифицирован
  • Уровень вовлечённости (ER): Средний показатель вовлечённости аудитории составляет 18.51%. В первые 24 часа после публикации контент обычно набирает 7.49% реакций от общего числа подписчиков.
  • Охват публикаций: В среднем каждый пост получает 3 390 просмотров. В течение первых суток публикация набирает 1 371 просмотров.
  • Реакции и взаимодействия: Аудитория активно поддерживает контент: среднее количество реакций на один пост — 0.
  • Тематические интересы: Контент сосредоточен на ключевых темах, таких как .net, api, логика, архитектура, string.

📝 Описание и контентная политика

Автор описывает ресурс как площадку для выражения субъективного мнения:
По всем вопросам- @notxxx1 Реестр РКН: https://clck.ru/3Fk3kb #VRHSZ

Благодаря высокой частоте обновлений (последние данные получены 14 июня, 2026) канал поддерживает актуальность и высокий уровень охвата публикаций. Аналитика показывает, что аудитория активно взаимодействует с контентом, что делает его важной точкой влияния в категории Технологии и приложения.

18 308
Подписчики
+724 часа
+47 дней
-330 день
Архив постов
#ПятничныйКвиз #карательныйсишарп
#ПятничныйКвиз #карательныйсишарп

🖥 Xeno RAT опубликован на GitHub ⏩Недавно на GitHub был опубликован новый продвинутый инструмент для удалённого доступа (RAT
🖥 Xeno RAT опубликован на GitHub ⏩Недавно на GitHub был опубликован новый продвинутый инструмент для удалённого доступа (RAT) под названием Xeno RAT. Этот троян, написанный на языке программирования C# и совместимый с операционными системами Windows 10 и Windows 11, предоставляет «обширный набор функций для удалённого управления системой», согласно заявлениям разработчика под псевдонимом moom825. В функционал Xeno RAT входит обратный прокси-сервер SOCKS5, возможность записи аудио в реальном времени, а также интеграция модуля скрытого виртуального сетевого вычисления (hVNC), подобного DarkVNC, который позволяет злоумышленникам получать удалённый доступ к заражённому компьютеру. ⏩Разработчик отдельно отметил «весёлые» функции своего инструмента, такие как «синий экран смерти» по запросу, отключение монитора удалённого хоста, открытие/закрытие лотка для компакт-дисков и т.п. Разработчик утверждает, что Xeno RAT был разработан исключительно в образовательных целях. А что, неплохая идея для пет-проекта на C# ¯\_(ツ)_/¯ 🖥 GitHub @csharp_ci

Хотите разрабатывать современное ПО и узнать, какие структуры данных помогут вам создавать эффективные алгоритмы? Присоединяй
Хотите разрабатывать современное ПО и узнать, какие структуры данных помогут вам создавать эффективные алгоритмы? Присоединяйтесь к открытому практическому вебинару «Коллекции и структуры данных» от OTUS!  Мы расскажем о массивах, списках, словарях и других структурах данных, их реализации в .NET, способах оптимизации производительности и выборе наиболее подходящей структуры.  Урок пройдет 16 мая в 20:00 мск и будет приурочен к старту большого курса «Специализация C# Developer». После вебинара вы получите специальную цену на обучение и персональную консультацию от наших менеджеров!  Регистрируйтесь прямо сейчас, чтобы не пропустить бесплатный урок: https://clck.ru/3AVxX8?erid=LjN8KYB6c  Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963.

🖥 Amvera добавила поддержку Go, Ruby и С# (dotnet и mono) окружений 🟡Amvera Cloud — облако для ботов, сайтов и других IT-пр
🖥 Amvera добавила поддержку Go, Ruby и С# (dotnet и mono) окружений 🟡Amvera Cloud — облако для ботов, сайтов и других IT-приложений c функционалом простого деплоя через Git и интерфейс. 🟡C апреля 2024 г. в Amvera Cloud доступна встроенная поддержка для развертывания С# (dotnet и mono) окружений к текущим Python, Java, Node.JS и Docker. То есть теперь, если ваше приложение на C# (или Golang и Ruby), не нужно писать Dockerfile, можно просто задать конфигурацию в интерфейсе и загрузить файлы проекта через push в Git-репозиторий или интерфейс личного кабинета. После этого развертывание, установка зависимостей и настройка произойдут автоматически. 📎 Подробнее @csharp_ci

🌟 Присоединяйтесь к нам на мероприятие EXOZ { "meetup" : "c#/.net" }! 🌟 🗓 Дата: 26 мая 2024 года 📍 Место проведения: Офла
🌟 Присоединяйтесь к нам на мероприятие EXOZ { "meetup" : "c#/.net" }! 🌟 🗓 Дата: 26 мая 2024 года 📍 Место проведения: Офлайн: г. Калуга, ул. Академика Королева 16, Four Points by Sheraton Онлайн: присоединяйтесь из любой точки мира! 🎉 Что вас ждет на мероприятии: - 4 доклада от опытных специалистов; - Эксклюзивный мерч от нас и наших партнеров; - Активности на перерывах; - Кофебрейки; - Дискуссии со спикерами; - Розыгрыши призов; - Нетворкинг; - Фотоотчет и видеозаписи мероприятия; - Специальная скидка на проживание в Four Points by Sheraton; - After Party; 🎙 Доклады: 1. Ярослав Румякин. Астрал.Софт: "Введение в архитектуру Web-приложений" 2. Юлия Короходкина. Правое полушарие интроверта: "Обратная связь в команде: говорить нельзя молчать" 3. Константин Волоховский. PVS-Studio: "Чем статический анализ кода полезен C# программисту" 4. Дмитрий Бахтенко. Skillaz: "Динамическое добавление провайдеров аутентификации openid connect в .net core приложении" 🔗 Зарегистрируйтесь по ссылке сейчас, кол-во мест на офлайн ограничено: Регистрация Присоединяйтесь к нашему сообществу и поднимите свои навыки на новый уровень! 🚀

🖥 AutoFixture — для быстрого написания модульных тестов AutoFixture — это библиотека .NET, основная цель которой — позволить
+1
🖥 AutoFixture — для быстрого написания модульных тестов AutoFixture — это библиотека .NET, основная цель которой — позволить разработчикам сосредоточиться на том, что тестируется, а не на том, как настроить сценарий тестирования. AutoFixture автоматизирует настройку неактуальных тестовых приспособлений, позволяя разработчику тестов сосредоточиться на основных аспектах каждого тест-кейса. 🖥 GitHub 🟡 Доки @csharp_ci

🖥 Развертывание ASP.NET Core приложений на Ubuntu Linux Здесь мы рассмотрим последовательность действий для развертывания AS
+1
🖥 Развертывание ASP.NET Core приложений на Ubuntu Linux Здесь мы рассмотрим последовательность действий для развертывания ASP.NET Core сервиса в Ubuntu Linux. От создания и адаптации приложения, до его развертывания и запуска. Разберём вопросы регистрации репозиториев Microsoft, установки Apache и .NET, настройки реверс-прокси и некоторой диагностики. ▶️ Начинаем @csharp_ci

🔥Подборка лучших обучающих каналов для программистов. ➡️ Делитесь с коллегами и сохраняйте себе, чтобы не потерять ⚡Машинное обучение Machine Learning - запускаем лучшие ИИ модели, пишем код, погружаемся в нейросети Ml Собеседование - подготовка к собесу по мл, алгоритмам, коду Ml ru - актуальные статьи, новости, код и обучающие материалы Ml Jobs - вакансии ML ML Книги - актуальные бесплатные книги МО ML чат 🏆 Golang Golang Golang собеседование - разбор задач и вопросов с собесов Golang вакансии -работа для Go разработчика Golang книги библиотека книг Golang задачи и тесты Golang чат Golang news - новости из мира go Golang дайджест 💥 Linux /Этичный хакинг Linux Academy - гайды, секреты и лучшие материалы по Linux Kali linux - погрузись в мир этичного хакинга и кибербезопасности linux_kal - kali чат Информационная безопасность 🚀 Data Science Анализ данных - полезные фишки, код, гайды и советы, маст-хэв датасаентиста Data Jobs - ds вакансии Аналитик данных Data Science книги - актуальные бесплатные книги Big data 🛢Базы данных Sql базы данных - научим работе с базами данных профессионально Библиотека баз данных SQL чат Вакансии Sql аналитик данных #️⃣C# С# академия - лучший канал по c# С# заметки — код, лучшие практики, заметки программиста c# С# задачи и тесты С# библиотека - актуальные бесплатные книги C# вакансии - работа 🐍 Python Python/django - самый крупный обучающий канал по Python Python Собеседование - подготовка к собеседовению python и разбор алгоритмов Pro python - статьи, новости, код и обучающие материалы Python Jobs - вакансии Python Python чат Python книги ☕ Java Java академия - java от Senior разработчика Java вакансии Java чат Java вопросы с собеседований Java книги 💻 C++ C++ академия С++ книги C++ задачи - подготовка к собеседовению мл, алгоритмам C++ вакансии ⚡️ Frontend Javascript академия - крупнейший js канал React - лучшие гайды и советы по работе с react Frontend - тутрориалы, уроки, гайды, код PHP Книги frontend Задачи frontend 🦀 Rust Rust программирование Rust чат Rust книги для программистов 📲 Мобильная разработка Android разработка Мобильный разработчик гайды и уроки 🇬🇧 Английский для программистов 🧠 Искусственный интеллект ИИ и технологии Neural - нейросети для работы и жизни Книги ИИ Artificial Intelligence 🔥 DevOPs Devops для программистов Книги Devops 🌟 Docker/Kubernets Docker Kubernets 📓 Книги Библиотеки Книг для программситов 💼 Папка с вакансиями: Папка Go разработчика: Папка Python разработчика: Папка Data Science Папка Java разработчика Папка C# Папка Frontend 💥 Бесплатный Chatgpt бот

🖥 Факт дня — семафоры в C# Семафоры позволяют ограничить количество потоков, которые имеют доступ к определенным ресурсам. В .NET семафоры представлены классом Semaphore. Для создания семафора применяется один из конструкторов класса Semaphore: 🟡Semaphore (int initialCount, int maximumCount) параметр initialCount задает начальное количество потоков, а maximumCount — максимальное количество потоков, которые имеют доступ к общим ресурсам: initialCount — изначальное доступное количество свободных мест, maximumCount — вместимость. 🟡Semaphore (int initialCount, int maximumCount, string? name) в дополнение задает имя семафора 🟡Semaphore (int initialCount, int maximumCount, string? name, out bool createdNew): последний параметр — createdNew при значении true указывает, что новый семафор был успешно создан. Если этот параметр равен false, то семафор с указанным именем уже существует Для работы с потоками класс Semaphore имеет 2 основных метода: — WaitOne() ожидает получения свободного места в семафоре — Release() освобождает место в семафоре В отличие от lock (Monitor) и Mutex, у Semaphore нет «владельца» — он не зависит от потока. Любой поток может вызвать Release на семафоре, тогда как с Mutex и блокировкой только поток, получивший блокировку, может ее освободить.
// запускаем пять потоков
for (int i = 1; i < 6; i++)
{
    Reader reader = new Reader(i);
}
class Reader
{
    // создаем семафор
    static Semaphore sem = new Semaphore(3, 3);
    Thread myThread;
    int count = 3;// счетчик чтения
 
    public Reader(int i)
    {
        myThread = new Thread(Read);
        myThread.Name = $"Читатель {i}";
        myThread.Start();
    }
 
    public void Read()
    {
        while (count > 0)
        {
            sem.WaitOne();  // ожидаем, когда освободиться место
 
            Console.WriteLine($"{Thread.CurrentThread.Name} входит в библиотеку");
 
            Console.WriteLine($"{Thread.CurrentThread.Name} читает");
            Thread.Sleep(1000);
 
            Console.WriteLine($"{Thread.CurrentThread.Name} покидает библиотеку");
 
            sem.Release();  // освобождаем место
 
            count--;
            Thread.Sleep(1000);
        }
    }
}
@csharp_ci

🚀 Готовься к переменам в мире IT с нашим практическим курсом по Domain Driven Design! 😰 Устал от запутанной инфраструктуры,
🚀 Готовься к переменам в мире IT с нашим практическим курсом по Domain Driven Design! 😰 Устал от запутанной инфраструктуры, вперемешку с бизнес логикой? Мы знаем, как это тяжело. Писать тесты становится неприятно и больно, много приходится мокать, тесты получаются огромными, хрупкими.. Но есть решение! Присоединяйся к нашему курсу, где мы разложим все по полочкам за 10 вебинаров, начиная с 13 мая. 🔝 Прими вызов и стань частью передовой волны технологического прогресса. Успей зарегистрироваться уже сейчас https://microarch.ru/courses/hexagonal-architecture?utm_source=posev&utm_medium=erid:2VtzqvmkXyj&utm_campaign=2 🎓 На нашем курсе ты изучишь: ✅ Основы Domain-Driven Design и его важность для разработчиков. ✅ Создание эффективных и масштабируемых сервисов с использованием DDD. ✅ Применение шаблонов проектирования и принципов DDD для оптимизации кода и повышения производительности. 💡 Зачем тебе этот курс? 🌟 Плюс, ты получишь: — Новые подходы к разработке, в том числе и использование подходов ядра и слоев в онион-архитектуре. — Шанс быть первым внедрившим новые методы в отделе. — Стань Senior Developer или Team Lead. — Пиши код как профессионал, а не как в учебниках. — Получи признание в компании и увеличь свою заработную плату. 🌟 Присоединяйся к нам прямо сейчас и стань экспертом в разработке успешных проектов: https://microarch.ru/courses/hexagonal-architecture?utm_source=posev&utm_medium=erid:2VtzqvmkXyj&utm_campaign=2 Реклама. ИП Ветчинкин К.Е. ИНН: 773376451099 Erid: 2VtzqvmkXyj

В какой строке возникнет первое исключение DivideByZeroException?
Anonymous voting

#ПятничныйКвиз #карательныйсишарп
#ПятничныйКвиз #карательныйсишарп

🖥 Zenject, внедрение зависимостей, Unity C# Очень понятное объяснение, что же такое Zenject, Dependency Injection и всё тако
+2
🖥 Zenject, внедрение зависимостей, Unity C# Очень понятное объяснение, что же такое Zenject, Dependency Injection и всё такое Рекомендую) Что внутри? • 00:36 - Другие годные источники по зенджекту • 02:20 - Что такое Dependency Injection? • 03:39 - Проблема DI — большое количество сервисов • 04:02 - Проблема DI — вложенные зависимости • 04:56 - Проблема DI — разное время жизни сервисов • 05:45 - Что делает Zenject? • 06:35 - Binding в Zenject • 07:54 - Installer-s в Zenject • 09:16 - Context в Zenject • 10:54 - Как это всё работает • 11:54 - Дополнительные инструменты Zenject-а • 13:04 - ITickable, IInitializable и IDisposable 📎 YouTube 🖥 GitHub @csharp_ci

🖥 Многопоточное vs асинхронное программирование ▶️Вообще, есть несколько разных понятий: • Конкурентное исполнение • Паралле
🖥 Многопоточное vs асинхронное программирование ▶️Вообще, есть несколько разных понятий: • Конкурентное исполнение • Параллельное исполнение • Многопоточное исполнение • Асинхронное исполнение Каждый из этих терминов строго определен и имеет четкое значение. 🟡Конкурентность Конкурентность — это наиболее общий термин, который говорит, что одновременно выполняется более одной задачи. 🟡Параллельное исполнение Параллельное исполнение подразумевает наличие более 1 вычислительного устройства (например, процессора), которые будут одновременно выполнять несколько задач. Параллельное исполнение — это строгое подмножество конкурентного исполнения. Это значит, что на компьютере с 1 процессором параллельное программирование - невозможно 🟡Многопоточность Многопоточность — это один из способов реализации конкурентного исполнения путем выделения абстракции "рабочего потока" (worker thread). Потоки "абстрагируют" от пользователя низкоуровневые детали и позволяют выполнять более чем одну работу "параллельно". Операционная система, среда исполнения или библиотека прячет подробности того, будет многопоточное исполнение конкурентным (когда потоков больше чем физических процессоров), или реально параллельным. 🟡Асинхронное исполнение Асинхронность подразумевает, что операция может быть выполнена кем-то на стороне: удаленным веб-узлом, сервером или другим устройством за пределами текущего вычислительного устройства. ▶️Ну или более неформально: скажем, вам нужно выкопать во дворе бассейн. • Вы взяли лопату и копаете. Это однопоточная работа • Вы пригласили друга Васю и копаете вместе, периодически задевая друг-друга лопатами. Это многопоточная работа • Пока вы копаете бассейн, Вася копает канаву под водопровод. Никто никому не мешает. Это распараллеливание • Вы пригласили бригаду землекопов, а сами с Васей пошли отдыхать. Когда бригада все сделает, к вам придут за деньгами. Это асинхронная работа. Количество лопат в хозяйстве - это количество ядер в системе 📎 Подробнее @csharp_ci

🖥 Ссылочные локальные переменные в C# 🟡Начиная с версии C# 7 в языке появилась возможность, позволяющая объявить локальную
🖥 Ссылочные локальные переменные в C# 🟡Начиная с версии C# 7 в языке появилась возможность, позволяющая объявить локальную переменную, ссылающуюся на элемент массива или на поле в объекте:
int[] simpleArray = {0, 1, 2, 3, 4, 5, 6, 7, 8};
ref int simpleElementRef = ref simpleArray[3];
В этом примере simpleElementRef — ссылка на simpleArray[3]. Изменение simpleElementRef приводит к изменению элемента массива:
simpleElementRef *= 15;
Console.WriteLine(simpleElementRef);      // 15
Console.WriteLine(simpleArray[3]);        // 15
🟡В качестве цели ссылочной локальной переменной может быть указан элемент массива, поле, или обычная локальная переменная. Целью не может быть свойство. Ссылочные локальные переменные используются для специальных сценариев микро-оптимизации и как правило применяются в сочетании с возвращаемыми ссылочными значениями. 🟡Также ссылочные локальные переменные можно возвращать из методов. В результате получаем возвращаемое ссылочное значение:
static string X = "Старое значение";
static ref string GetX() => ref X; // Возвращает ссылочное значение

static void Main()
{
   ref string xRef = ref GetX(); // Присваивает результат ссылочной локальной переменной
            
   xRef = "Новое значение";
            
   Console.WriteLine(X); // Выводит Новое значение
}
📎 Подробнее @csharp_ci

🖥 Факт дня — Task.Yield() Повторение — мать учения и основа научного метода, так что приступим) Task.Yield() возвращает специальное значение, предназначенное для передачи оператору await, и в отрыве от этого оператора не имеющее смысла. Конструкция же await Task.Yield() делает довольно простую вещь — прерывает текущий метод и сразу же планирует его продолжение в текущем контексте синхронизации. Используется же эта конструкция для разных целей. 🟡Во-первых, эта конструкция может быть использована для немедленного возврата управления вызывающему коду. Например, при вызове из обработчика события событие будет считаться обработанным:
protected override async void OnClosing(CancelEventArgs e)
{
    e.Cancel = true;
    await Task.Yield(); 
    // (какая-то логика)
}
🟡Во-вторых, эта конструкция используется для очистки синхронного контекста вызова. Например, так можно "закрыть" текущую транзакцию (ambient transaction):
using (var ts = new TransactionScope()) {
  // ...
  Foo();
  // ...
  ts.Complete();
}

async void Foo() {
  // ... тут мы находимся в контексте транзакции
  if (Transaction.Current != null) await Task.Yield();
  // ... а тут его уже нет!
}
🟡В-третьих, эта конструкция может очистить стек вызовов. Это может быть полезным, если программа падает с переполнением стека при обработке кучи вложенных продолжений. Например, рассмотрим упрощенную реализацию AsyncLock:
class AsyncLock
{
    private Task unlockedTask = Task.CompletedTask;

    public async Task<Action> Lock()
    {
        var tcs = new TaskCompletionSource<object>();

        await Interlocked.Exchange(ref unlockedTask, tcs.Task);

        return () => tcs.SetResult(null);
    }
}
Здесь поступающие запросы на получение блокировки выстраиваются в неявную очередь на продолжениях. Казалось бы, что может пойти не так?
private static async Task Foo()
{
    var _lock = new AsyncLock();
    var unlock = await _lock.Lock();

    for (var i = 0; i < 100000; i++) Bar(_lock);

    unlock();
}

private static async void Bar(AsyncLock _lock)
{
    var unlock = await _lock.Lock();
    // do something sync
    unlock();
}
Здесь продолжение метода Bar вызывается в тот момент, когда другой метод Bar выполняет вызов unlock(). Получается косвенная рекурсия между методом Bar и делегатом unlock, которая быстро сжирает стек и ведет к его переполнению. Добавление же вызова Task.Yield() перенесет исполнение в "чистый" фрейм стека, и ошибка исчезнет:
class AsyncLock
{
    private Task unlockedTask = Task.CompletedTask;

    public async Task<Action> Lock()
    {
        var tcs = new TaskCompletionSource<object>();

        var prevTask = Interlocked.Exchange(ref unlockedTask, tcs.Task);

        if (!prevTask.IsCompleted) 
        {
          await prevTask;
          await Task.Yield();
        }

        return () => tcs.SetResult(null);
    }
}
@csharp_ci

Что выведет этот код?
Anonymous voting

#ПятничныйКвиз #карательныйсишарп
#ПятничныйКвиз #карательныйсишарп

🖥 Как запустить C# юнит-тесты на Linux в GitHub Actions? В этой статье мы разберёмся с запуском C#-тестов на Linux и последу
+2
🖥 Как запустить C# юнит-тесты на Linux в GitHub Actions? В этой статье мы разберёмся с запуском C#-тестов на Linux и последующую публикацию их в открытом репозитории кода на GitHub. План: ├╼ Устанавливаем .NET на Ubuntu 22.04 ├╼ Создаём проект ├╼ Запускаем сборку в GitHub Actions ├╼ Используем секреты в коде тестов ╰╼ Размещаем секреты в GitHub Actions Secrets 📎 Туториал 🖥 GitHub @csharp_ci

🖥 Как можно реализовать ограничение на одновременное скачивание файлов? ▶️Итак, есть сервис, который отдает пользователям видео файлы, реализован метод для скачивания файла, который отдает файл через метод 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