C# Portal | Программирование
13.2K subscribers
1.44K photos
132 videos
31 files
1.08K links
Присоединяйтесь к нашему каналу и погрузитесь в мир для C#-разработчика

Сотрудничество, реклама: @devmangx

Работаем с @Spiral_Yuri

РКН: https://clck.ru/3FocB6
Download Telegram
Message Brokers гарантируют At-Least-Once, а не Exactly-Once

Что произойдёт, если ваш consumer обработает одно и то же событие дважды? Сможет ли система корректно справиться с повторной доставкой?

Брокеры сообщений часто используют семантику доставки At-Least-Once — событие будет доставлено как минимум один раз, но возможны дубликаты.

Поэтому обработчики событий должны быть идемпотентными (Idempotent): повторная обработка одного и того же события не должна приводить к повторным побочным эффектам.

Разберём, как проектировать идемпотентные обработчики событий и защищать систему от дублирующей обработки.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2🍾1
Зачем обрабатывать элементы по одному, если процессор может обрабатывать сразу 8?

В C# есть инструменты для использования SIMD (Single Instruction, Multiple Data) — технологии, которая позволяет выполнять одну операцию одновременно над несколькими элементами данных.

Для этого можно использовать Vector<T> и Hardware Intrinsics.

Что они дают?

Vector<T> — позволяет обрабатывать несколько значений одного типа за одну операцию.

Hardware Intrinsics — дают более низкоуровневый доступ к SIMD-инструкциям процессора, например AVX2 и AVX-512.

SIMD — ускоряет вычисления над массивами чисел, обработку изображений, математические операции и другие задачи с однотипными данными.

И всё это доступно прямо в C# — без необходимости переходить на C++.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔5👍2🔥2🍾1
Учитывают ли ваши C#-структуры кэш-линии процессора?

Неправильное расположение полей структуры приводит к неэффективному использованию памяти и дополнительным затратам на доступ к кэш-линии процессора.

Используйте [StructLayout(LayoutKind.Sequential, Pack = 1)], чтобы контролировать размещение полей в памяти.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2🤔2👏1🍾1
Каждый раз, когда асинхронный метод возвращает Task<T>, при завершении операции выделяется память в куче.

Если ваш метод часто завершается синхронно (например, при попадании в кеш), используйте ValueTask<T>.

Это поможет избежать миллионов лишних выделений памяти (heap allocations).


👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾4
Запускаете несколько реплик фонового воркера в Kubernetes?

Локальные блокировки (lock / Monitor) не работают между разными контейнерами.

Используйте распределённые блокировки Redis (Redis Distributed Locks) с fencing-токенами, чтобы предотвратить состояния гонки (race conditions) и избежать одновременного выполнения одной задачи несколькими воркерами.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3❤‍🔥2🍾2
Получаете случайные ошибки 502 Bad Gateway во время деплоя в Kubernetes?

Вероятно, ваше .NET-приложение завершает работу до того, как входящий трафик будет перенаправлен на другие экземпляры.

Разберитесь, как правильно настроить graceful shutdown и health probes в ASP.NET Core.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾3
Task.WhenAll vs Parallel.ForEachAsync в .NET: что выбрать?

Оба инструмента позволяют выполнять независимые операции конкурентно, но отличаются способом управления параллельностью и ресурсами.

Правильный выбор зависит от типа нагрузки.

1. Task.WhenAll. Лучше всего подходит для известного набора независимых асинхронных операций, особенно связанных с вводом-выводом (I/O-bound).

var usersTask = GetUsersAsync();
var ordersTask = GetOrdersAsync();

await Task.WhenAll(usersTask, ordersTask);


• Идеален для нескольких независимых запросов к API или базе данных.
• Не имеет встроенного ограничения количества одновременно выполняемых операций.
• Не создаёт потоки автоматически.

2. Parallel.ForEachAsync. Лучше всего подходит для обработки коллекций с контролируемым уровнем параллельности.

await Parallel.ForEachAsync(
orders,
new ParallelOptions
{
MaxDegreeOfParallelism = 10
},
async (order, ct) =>
await ProcessOrderAsync(order, ct));


• Поддерживает I/O-bound и CPU-bound нагрузки.
• Имеет встроенный механизм ограничения параллельности.
• Полезен при обработке больших коллекций и выполнении внешних API-запросов.

3. Что выбрать?

• CPU-bound: предпочитайте Parallel.ForEach для синхронных операций с высокой вычислительной нагрузкой.
• I/O-bound: используйте Task.WhenAll для нескольких независимых операций или Parallel.ForEachAsync, если необходимо ограничить параллельность.

Внешние API: подходят оба варианта, но Parallel.ForEachAsync часто удобнее для обработки сотен запросов без чрезмерной нагрузки на внешние сервисы.

Важное напоминание об EF Core: DbContext не является потокобезопасным (thread-safe).

Никогда не выполняйте параллельные запросы через один и тот же экземпляр DbContext. Используйте отдельные экземпляры или выполняйте запросы последовательно.

Главное:

• Task.WhenAll ожидает завершения нескольких задач без встроенного ограничения параллельности.

• Parallel.ForEachAsync обрабатывает коллекции с ограниченным уровнем параллельности.

И помните: по умолчанию Parallel.ForEachAsync допускает количество одновременно выполняемых операций, равное Environment.ProcessorCount. Настраивайте MaxDegreeOfParallelism с учётом особенностей вашей нагрузки.

Какой из этих инструментов вы чаще используете в production-приложениях на .NET?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🍾1
CQRS ≠ MediatR.

Перестаньте смешивать CQRS и MediatR.

То, что вы используете MediatR, не означает, что у вас реализован CQRS.

CQRS — это про разделение операций чтения и записи, часто с разными моделями, стратегиями хранения и иногда с разными хранилищами данных.

MediatR — это библиотека для диспетчеризации сообщений внутри процесса. Она удобна для организации команд и запросов, но это не фреймворк CQRS.

Можно использовать MediatR в архитектуре, построенной по CQRS.

Но не стоит считать, что одно автоматически означает другое.

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

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9👏1🍾1
Бесплатный декомпилятор .NET

Инструмент позволяет декомпилировать приложения в C#, восстанавливать целые проекты, искать методы и классы, изучать иерархию типов и просматривать метаданные.

Также доступен в виде расширений для Visual Studio и VS Code, а для работы из терминала есть CLI-версия.

https://github.com/icsharpcode/ILSpy

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🐳2🍾1
Бенчмарки First vs Single в .NET

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾2
Повышение производительности AsSplitQuery в Entity Framework 11

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9🍾1
Отличная шпаргалка для C#-разработчиков, которые регулярно работают с Git.

Создание коммитов, переключение между ветками, разрешение конфликтов, отмена изменений, работа с удалёнными репозиториями и история проекта.
80 команд с короткими пояснениями и примерами.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🍾2
Строка, которая рассчитывает скидку, спрятана за четырьмя вложенными if.

Каждая проверка добавляет новый уровень вложенности, а каждый else возвращает ноль. Чтобы понять, когда применяется скидка, приходится держать в голове все четыре условия.

Можно начать с обработки случаев, при которых скидка не предоставляется.

Если заказ или клиент отсутствует — метод завершается. То же самое происходит, если клиент неактивен или сумма заказа слишком мала для получения скидки.

После прохождения всех проверок последняя строка может сразу выполнить основную логику.

Правила остаются прежними, но вложенность становится меньше.

Это не означает, что в коде стало меньше ветвлений, а низкая цикломатическая сложность сама по себе ещё не делает код понятным.

Я проверяю, насколько легко проследить каждый путь выполнения, не возвращаясь постоянно к предыдущим строкам.

При рефакторинге обязательно сохраняйте тесты для граничных случаев.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🍾1
Хотите, чтобы скиллы ИИ-агентов всегда соответствовали версиям NuGet-пакетов?

Добавляйте скиллы прямо в пакеты — тогда агенты будут получать инструкции, актуальные именно для используемой версии библиотеки.

Читать подробнее.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾3❤1
Вышел Arch Guard v0.4.0 — инструмент для проверки архитектуры .NET-проектов. Помогает разработчикам и ИИ-агентам следить за структурой кода и не допускать архитектурных нарушений.

Попробовать: https://kbourzayq.github.io/arch-guard/

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🍾2
8 ПАТТЕРНОВ КЕШИРОВАНИЯ, которые должен знать C#-разработчик

Кеширование помогает ускорить приложение, снизить нагрузку на базу данных и эффективнее использовать ресурсы. Но важно не просто добавить Redis или MemoryCache, а выбрать подходящую стратегию.

Разбираем основные подходы:

Cache-Aside (Lazy Loading) — приложение сначала проверяет кеш. Если данных нет, загружает их из БД и сохраняет в кеше. Самый распространённый вариант.

Read-Through — приложение запрашивает данные у кеша, а тот самостоятельно загружает их из БД при промахе.

Write-Through — данные одновременно записываются в кеш и БД. Помогает поддерживать согласованность, но увеличивает задержку записи.

Write-Behind (Write-Back) — приложение сначала записывает данные в кеш, а в БД они попадают асинхронно. Выше производительность, но есть риск потери данных.

Write-Around — запись идёт напрямую в БД, минуя кеш. Подходит для данных, которые редко читают.

Refresh-Ahead — кеш заранее обновляет часто используемые данные, не дожидаясь их истечения. Помогает избежать промахов кеша.

TTL + Eviction — TTL задаёт срок жизни записи, а политики вытеснения вроде LRU и LFU определяют, какие данные удалить при нехватке памяти.

Distributed Cache — общий кеш для нескольких экземпляров приложения. В .NET для этого можно использовать IDistributedCache и Redis.

В экосистеме .NET также есть HybridCache — механизм, объединяющий кеш в памяти и распределённый кеш. Он поддерживает защиту от одновременной загрузки одних и тех же данных несколькими запросами.

Главное — выбирать стратегию под сценарий: частоту чтения и записи, требования к согласованности и допустимость потери данных.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍1🍾1
12 МЕТОДОВ LINQ, КОТОРЫЕ ДОЛЖЕН ЗНАТЬ КАЖДЫЙ C#-РАЗРАБОТЧИК

LINQ делает код на C# чище, короче и проще в поддержке.
Вот 12 методов, которые стоит освоить:

• Where() — фильтрует элементы по условию.
• Select() — преобразует элементы в новую форму.
• SelectMany() — объединяет вложенные коллекции в одну.
• Any() — проверяет, есть ли хотя бы один подходящий элемент.
• All() — проверяет, соответствуют ли условию все элементы.
• DistinctBy() — удаляет дубликаты по заданному ключу.
• GroupBy() — группирует элементы по общему ключу.
• OrderBy() — сортирует элементы по возрастанию.
• FirstOrDefault() — возвращает первый подходящий элемент или значение по умолчанию.
• MaxBy() — находит элемент с максимальным значением ключа.
• Chunk() — разбивает коллекцию на пакеты.
• Aggregate() — объединяет элементы в один результат.

Многие LINQ-запросы используют отложенное выполнение (Deferred Execution). Особенно важно понимать, когда именно выполняется запрос при работе с EF Core.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍2🍾1
ВЫШЛИ .NET 11 И C# 15! Этот релиз приносит масштабные улучшения во всю экосистему .NET.

От Union Types и Runtime Async до новых API, повышения производительности и мощных возможностей EF Core.

Вот ключевые обновления, которые должен знать каждый .NET-разработчик

1. C# 15

• Union Types — моделирование нескольких возможных типов с проверкой полноты обработки через switch.
• Closed Hierarchies — ограничение наследования пределами сборки, в которой объявлен тип.
• Collection Expressions — поддержка передачи аргументов конструкторам с помощью with(...).
• Extension Indexers — добавление индексаторов к существующим типам.
• Labeled Break/Continue — управление выходом из внешних циклов и переходами между ними.
• Memory Safety (Preview) — улучшенная безопасность при работе с неуправляемой памятью.

2. .NET 11 Runtime

• Runtime Async (Preview) — снижение накладных расходов на асинхронность и более понятные трассировки стека.
• JIT Optimizations — улучшенная девиртуализация и устранение проверок границ массивов.
• Native AOT — более быстрый вызов методов через интерфейсы.
• Diagnostics — формирование отчётов о сбоях непосредственно внутри процесса.

3. Библиотеки .NET 11

• LINQ — новые методы FullJoin и перегрузки Join, возвращающие кортежи.
• JSON — поддержка JSON Lines и сериализации Union Types.
• Compression — поддержка алгоритма сжатия Zstandard.
• Numeric Types — новые числовые типы Decimal32, Decimal64 и Decimal128.
• Validation — новые асинхронные API для валидации.

4. .NET 11 SDK и инструменты

• File-Based Apps — поддержка нескольких файлов с помощью #:include.
• dotnet test — улучшенное выполнение тестов и формирование отчётов.
• dotnet watch — автоматическое восстановление после сбоев.
• Native AOT CLI — более быстрый запуск CLI-приложений.

5. ASP.NET Core 11

• Async Validation — асинхронные валидаторы в Minimal APIs.
• Localization — встроенная локализация сообщений валидации.
• OpenAPI 3.2 — поддержка по умолчанию, включая схемы SSE.
• MCP — новый шаблон проекта MCP-сервера.
• HTTP/3 — снижение задержки при выполнении первых запросов.

6. EF Core 11

• Query Performance — более эффективная генерация SQL-запросов.
• FullJoin — преобразование запросов в SQL FULL JOIN.
• MaxBy/MinBy — поддержка трансляции в SQL.
• Vector Search (Experimental) — векторные индексы и поиск по сходству.
• Hybrid Search — объединение векторного и полнотекстового поиска.
• Vector Loading — возможность не загружать векторные столбцы по умолчанию.

Моё мнение:

Union Types — важное дополнение к C#, особенно для моделирования состояний приложения и результатов операций.

Runtime Async выглядит перспективно для высоконагруженных приложений, хотя пока остаётся экспериментальной возможностью.

А возможности векторного поиска в EF Core особенно интересны для создания AI-приложений на SQL Server.

Если вы уже используете .NET 10 LTS, срочной необходимости обновлять production-системы нет.

Но .NET 11 определённо стоит изучить!

Какая функция .NET 11 вас заинтересовала больше всего?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤3🍾1
Union Types появятся в C# 15. Я ждал эту возможность много лет.

Я уже немало писал о паттерне Result. Возьмём простой метод GetUser(42). Его возвращаемый тип — User. Чтобы узнать, что метод выбрасывает исключение, если пользователь с ID 42 не найден, приходится открывать его реализацию. Слишком много скрытой логики для обычного поиска.

С Union Types я смогу задать возвращаемый тип UserResult с двумя вариантами: User или NotFound. На уровне endpoint можно обработать результат через switch: для User вернуть HTTP 200, а для NotFound(42) — HTTP 404. При этом ID ненайденного пользователя никуда не теряется.

Но больше всего меня радует то, что будет дальше. Допустим, мы добавим третий вариант. Компилятор укажет на все выражения switch, которые по-прежнему обрабатывают только два случая. Можно сразу исправить их, пока изменения ещё свежи в памяти.

Как начать работать с Union Types

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7
This media is not supported in your browser
VIEW IN TELEGRAM
Как насчёт партии в Backend? 😴

Дело в чём: 17 ноября AvitoTech проводит Backend Roulette. Инженерные задачи там разложат как покерную партию: за каждым столом эксперт-крупье AvitoTech даст команде вводные, а по ходу игры добавит новые обстоятельства, чтобы перестроить решение.

Можно не садиться за стол и провести время на сайд-активностях или в разговорах с коллегами. После игры всех гостей ждёт афтерпати и нетворк.

И главное: покерный опыт совсем не нужен, достаточно круто провести вечер и понетворкать!

✅ Зарегистрироваться
Please open Telegram to view this post
VIEW IN TELEGRAM
👀1