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

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

Менеджер: @Spiral_Yuri

РКН: https://clck.ru/3FocB6
Download Telegram
Служебные учётные записи задают контекст безопасности, который службы Windows, запланированные задачи и приложения используют для доступа к локальным и сетевым ресурсам.

В материале разбирается, что такое служебные учётные записи, какие проблемы они могут создавать, а также как выбрать и настроить подходящий тип локальной или управляемой учётной записи в Windows Server 2025.

https://learn.microsoft.com/en-us/training/modules/understand-windows-service-accounts/

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾2
В .NET есть коллекция, из которой данные читаются в 2–4 раза быстрее, чем из Dictionary

Большинство разработчиков ни разу её не использовали.

Она называется FrozenDictionary — а для множеств есть FrozenSet. Обе коллекции появились в .NET 8.

Идея простая:

> Создаёте коллекцию один раз, читаете из неё много раз и больше никогда не изменяете.

Такие данные наверняка уже есть в ваших проектах:

- коды стран;
- названия ролей;
- feature flags;
- разрешённые расширения файлов.

Вы загружаете их при старте приложения и больше не меняете.

Но обычный Dictionary об этом не знает.

Он по-прежнему готов к добавлению и удалению элементов, а также к изменению размера — операциям, которые вы никогда не выполните. За эту гибкость приходится платить при каждом чтении.

Почему Frozen-коллекции быстрее

Когда вы вызываете ToFrozenDictionary, .NET тратит дополнительное время на анализ данных.

После этого он выбирает наиболее подходящую внутреннюю структуру:

- для коротких строковых ключей используется оптимизированное хеширование;
- для небольших диапазонов целых чисел может применяться прямая индексация;
- для маленьких множеств используется быстрый линейный поиск.

Вы один раз платите за создание коллекции и затем постоянно получаете более быстрые операции чтения.

Компромисс простой:

- создание медленнее в 2–10 раз;
- чтение быстрее в 2–4 раза, а для строк выигрыш может быть ещё больше.

Когда использовать

- Для lookup-таблиц, которые загружаются при старте и больше не изменяются.
- Вместо длинного switch по строковым литералам — например, с проверкой через Contains.
- Для любой коллекции с большим количеством операций чтения, которая создаётся один раз на запрос.

Когда не использовать

- Если коллекция должна изменяться после создания: методов Add и Remove нет.
- Если данные будут прочитаны всего несколько раз.
- Если проект всё ещё работает на .NET 7 или более старой версии.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍113🍌2🍾1
.NET 11 Preview 6 включает Extension Indexers из C# 15.

Например, теперь можно расширять такие типы, как IReadOnlyList<T>, чтобы получать последний элемент через ^1 — без изменения самой коллекции и без дублирования вспомогательной логики.
Более выразительный код и более естественные API.

#dotnet #CSharp #NET11

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍3🍾2
This media is not supported in your browser
VIEW IN TELEGRAM
Postgres 19 обрабатывает всплески нагрузки так, как и должна работать инфраструктура.

Не за счёт одного фиксированного пула I/O-воркеров, рассчитанного на некий вымышленный «средний» день.

А динамически.

→ Нагрузка резко растёт
→ Очередь операций ввода-вывода увеличивается
→ PostgreSQL это замечает
→ Запускаются дополнительные воркеры
→ Очередь разгружается
→ Когда нагрузка снижается, лишние воркеры завершают работу

Без ручного вмешательства.
Без постоянного избыточного резервирования ресурсов.

И без крошечного пула воркеров, который захлёбывается под продакшен-нагрузкой.

PostgreSQL превращается в инфраструктуру, которая сама адаптируется к нагрузке, а не требует, чтобы вы постоянно за ней присматривали.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🍾2
Паттерн Options в .NET — это одна из тех фич, которые я стабильно использую во всех своих C#-проектах

Более чистое управление конфигами
Сильно типизированные классы
Простая интеграция с DI
Без проблем работает с appsettings.json, secrets.json, Azure Key Vault и прочим

Почему это важно

Вместо того чтобы раскидывать значения конфигов по всему коду, ты централизуешь их в структурированных классах. Это не только улучшает читаемость, но и делает код более тестируемым и удобным в сопровождении.

Обычно это выглядит так

🔹Определяешь конфиг в appsettings.json
🔹Создаёшь POCO-класс
🔹Биндишь его через .AddOptions<T>().BindConfiguration()
🔹Инжектишь в сервисы через IOptions<T>

Просто. Масштабируемо. Аккуратно.

А ты используешь этот паттерн у себя или до сих пор дёргаешь значения конфигов через IConfiguration["key"] 😃

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥32🍾1
using var client = new HttpClient(); внутри цикла выглядит как ответственное управление ресурсами. На деле это утечка сокетов.

Каждый новый экземпляр HttpClient создаёт собственный пул соединений, а после вызова Dispose сокеты остаются в состоянии TIME_WAIT примерно на четыре минуты. Под нагрузкой доступные порты заканчиваются, и вы получаете SocketException, хотя сервер полностью исправен.

Вместо этого внедрите IHttpClientFactory. Одна строка — и проблема решена.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍4🍾2
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🍾1
Большинство senior-разработчиков советуют создавать репозитории для EF Core.

Но это не лучший подход к написанию кода.

По мере роста .NET-проектов работа с данными становится всё сложнее.

Многие команды начинают с паттерна Repository, оборачивая в него запросы EF Core.

Поначалу это работает нормально. Но по мере роста проекта репозитории либо делают недостаточно, либо пытаются делать слишком много.

Когда бизнес-требования меняются, код становится сложнее понимать и модифицировать.

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

Помните, что DbContext в EF Core уже реализует паттерны Repository и Unit of Work.

Это прямо указано в официальной документации Microsoft по DbContext. То же самое можно увидеть в описании класса DbContext в вашей IDE.

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

Как решить эту проблему? Ответ — паттерн 𝗦𝗽𝗲𝗰𝗶𝗳𝗶𝗰𝗮𝘁𝗶𝗼𝗻.

Паттерн Specification — это способ описать, какие данные вы хотите получить из базы данных, с помощью небольших переиспользуемых классов, называемых спецификациями.

Каждая спецификация представляет собой фильтр или правило, которое можно применить к запросу. Это позволяет создавать сложные запросы, комбинируя простые и понятные классы.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6👎41🍾1
Файловые приложения поддерживают ссылки на .dll через #:include.
Начиная с .NET 11 Preview 6

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍3🥰1🍾1
Не начинайте с микросервисов.

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

И вот почему.

У микросервисов есть своя цена:

* Координация между командами
* Работа со сбоями
* Eventual consistency
* Автоматизация деплоя
* Управление несколькими сервисами
* Развёртывание дополнительной инфраструктуры

В начале нового проекта эта сложность вам не нужна.

Даёт ли она ценность пользователям? Скорее всего, нет.

Опыт вашей команды играет значительную роль.

Если вы не умеете управлять большим монолитом, с микросервисами лучше не станет.

Определение границ сервисов требует большой работы. Насколько вы уверены, что сможете правильно провести их с самого начала?

Если вы ошибётесь, рефакторинг границ сервисов будет сложным. В монолите это сделать гораздо проще.

Вот менее рискованная стратегия:

* Начните с монолита
* Определите границы сервисов — bounded contexts
* Затем решите, действительно ли их нужно выделять в микросервисы

Есть и множество других факторов. Все их невозможно уместить в одном посте.

Но надеюсь, я дал вам пищу для размышлений.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾1
Microsoft подтвердила «значительное ускорение» поиска по разделу «Этот компьютер» в Проводнике Windows 11.

Маркус Эш, руководитель направления дизайна и исследований Windows, подтвердил, что улучшения скорости и релевантности, которые Microsoft внедряет в Windows Search, следующим этапом появятся в Проводнике. В первую очередь речь идёт о «значительном ускорении» поиска по всему разделу «Этот компьютер».

Это важно, потому что сейчас поиск по разделу «Этот компьютер» работает мучительно медленно.

Я протестировал поиск одного и того же файла через Windows Search и Проводник. Windows Search нашёл его примерно за секунду.

Поиск в Проводнике по всему разделу «Этот компьютер» занял более 8 минут.

И это был не перегруженный компьютер с тысячами файлов. Это был практически чистый тестовый ПК, на который почти ничего не было загружено.

Windows Search уже стал заметно лучше: более чистый интерфейс, меньше отвлекающих элементов, приоритет локальных результатов, обработка опечаток, поиск файлов по двум символам, поиск по подстроке и переключатель для отключения рекомендаций Bing и Microsoft Store.

Теперь эти улучшения поиска файлов наконец появятся и в Проводнике...

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯8🥴4😁3🍾1
Совет по Minimal API 💡

Как сделать обработчик чище?

Minimal API — это новый и лаконичный способ создавать REST API в .NET.

Один endpoint состоит из:

* extension-метода, соответствующего HTTP-методу
* маршрута
* обработчика

Обработчики часто пишут прямо в теле endpoint, но такой подход подходит только для простых случаев.

Что делать, когда код разрастается и становится перегруженным?

Использовать локальные функции.

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

В результате endpoints становятся чище, а логика оказывается инкапсулирована в одном месте.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
6🤔1🏆1🍾1
Я часто слышу, что C# — мусор и что с ним не стоит работать.

Вот почему, на мой взгляд, он лучше, чем считают некоторые:
В backend-разработке и CPU-intensive сценариях C# может быть значительно быстрее интерпретируемых языков и языков с динамической типизацией.

C# превосходит Python по скорости. Python-код обычно выполняется построчно во время работы программы, тогда как C# заранее компилируется, а затем дополнительно оптимизируется во время выполнения. У него очень эффективный runtime.
В CPU-intensive задачах и высоконагруженных backend-системах C# часто превосходит JavaScript и Node.js.

По производительности C# и Java обычно идут примерно на одном уровне.
Сравнение C# и Go неоднозначно. Go отлично подходит для сервисов, но C# предлагает более богатую экосистему, более продвинутые оптимизации runtime и мощные возможности языка.

C++ и Rust обычно быстрее C#, когда в приоритете максимальная производительность и полный контроль над памятью.

Но это лишь часть картины.

Что предлагает C#:
Производительность
Продуктивность разработчика
Строгая типизация
Поддерживаемость кода
Безопасная работа с памятью
Зрелая экосистема

JIT-компиляция оптимизирует участки кода, которые выполняются чаще всего.
Предварительная компиляция позволяет сократить время запуска и потребление памяти.
Сборщик мусора эффективно работает в приложениях с высокой пропускной способностью.
Разработчики могут использовать API вроде Span<T> и pipelines, чтобы уменьшать количество аллокаций и работать ближе к памяти.

Также C# позволяет создавать масштабируемые приложения, способные обрабатывать тысячи одновременных I/O-операций с помощью async и await.

Наконец, C# подходит для разработки самых разных типов приложений:
> ASP.NET Core — для Web API и backend-систем
> облачные сервисы и распределённые приложения
> WPF, WinUI и .NET MAUI — для desktop-приложений
> кроссплатформенные мобильные приложения
> игры на Unity
> background workers, планировщики и системы автоматизации
> AI-приложения и обработка данных с ML.NET

На C# также можно создавать serverless-функции, IoT-решения, CLI-инструменты, приложения реального времени и высокопроизводительные сетевые сервисы.

C# не всегда оказывается самым быстрым языком в каждом бенчмарке.
Но для многих реальных приложений он предлагает одно из лучших сочетаний производительности, продуктивности, инструментов и зрелости экосистемы.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍212🍾2
Поддержка .NET 8 заканчивается через четыре месяца

10 ноября 2026 года Microsoft прекратит поддержку .NET 8, поэтому уже сейчас стоит планировать переход на .NET 10.
.NET 10 относится к LTS-релизам и будет получать обновления до 14 ноября 2028 года.

Одно из главных изменений — заметный прирост производительности ASP.NET Core. По сравнению с .NET 8 он способен обрабатывать на 15% больше запросов в секунду. Для Minimal APIs потребление памяти также снизилось на 93%, что значительно уменьшает общий working set приложения.

Что нового появилось в .NET 10:

C# 14
В язык добавили extension members, присваивание через null-conditional оператор, ключевое слово field, модификаторы параметров в лямбда-выражениях, а также partial-конструкторы и события.

Файловые приложения
Теперь небольшой C#-код можно запускать прямо из одного файла .cs, без создания .sln и .csproj.

ASP.NET Core
Minimal APIs получили встроенную валидацию и поддержку JSON Patch. Также появились Server-Sent Events и поддержка OpenAPI 3.1.

EF Core
Добавлены опциональные complex types, поддержка JSON и структур, операторы LeftJoin и RightJoin, именованные query-фильтры и расширенные возможности ExecuteUpdate.

.NET Aspire
В Aspire 9.5 появился отдельный CLI, поддержка файлового AppHost, визуализатор генеративного ИИ, улучшенная трассировка, интеграция с хостингом OpenAI и поддержка эмуляторов Azure.

Blazor
Для Blazor WebAssembly добавили Hot Reload, настройку окружения, профилирование производительности и диагностические счётчики. Также улучшили роутинг, предварительную загрузку статических ресурсов и валидацию форм.

Библиотеки и Runtime
Появились новые API для криптографии, сериализации, коллекций, диагностики, числовых операций и работы с ZIP-файлами. Runtime получил улучшения JIT, NativeAOT, девиртуализации методов, стековых аллокаций и генерации кода, а также поддержку AVX10.2.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
2🍾1
Большинство разработчиков неправильно подходят к оптимизации SQL-запросов

Часто разработчики часами переставляют условия в WHERE, переписывают IN на EXISTS или добавляют query hints. Но в большинстве случаев это почти не влияет на производительность.

Современные СУБД и так умеют самостоятельно менять порядок JOIN и применять фильтры как можно раньше. Поэтому важнее не то, как именно записан запрос, а может ли база эффективно использовать индексы и правильно оценить объём данных.

Основной прирост скорости обычно дают три вещи.

Во-первых, фильтры должны позволять использовать индекс.
Например, если применить функцию к индексируемому столбцу:
EXTRACT(YEAR FROM order_date) = 2025
база может отказаться от использования индекса. Гораздо эффективнее задать диапазон по самому столбцу с датой.

Во-вторых, нужно правильно подбирать индексы.
В первую очередь стоит индексировать столбцы, которые участвуют в WHERE, JOIN и ORDER BY. При этом один составной индекс, например (status, order_date), часто работает лучше двух отдельных.

В-третьих, статистика таблиц должна быть актуальной.
Планировщик выбирает план выполнения на основе статистики. Если она устарела, база может выбрать неудачный план даже при хороших индексах.

Поэтому важнее правильно настроить индексы и статистику, чем бесконечно переписывать сам запрос.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍1👏1🍾1
Чувак рассказывает, как провалил техническое интервью из-за оптимизации одного отчётного запроса.
На маленьком объёме данных всё выглядело нормально: запрос выполнялся быстро. Но на тестовой базе с 500 000 строк он внезапно стал очень медленным.

Причина — скрытая проблема N+1: внутри SELECT был подзапрос, который выполнялся заново для каждой строки результата. То есть вместо одного обращения к базе происходили сотни тысяч повторных операций.

Решение оказалось простым — заменить такие подзапросы на JOIN, чтобы база могла обработать данные одним проходом.

Ещё одна частая ошибка — несколько одинаковых подзапросов для расчёта разных метрик. Например, отдельно считать сумму покупок клиента и количество заказов. Вместо этого лучше один раз собрать агрегированные данные через CTE, а потом присоединить результат.

Главный вывод: SQL, который летает на сотне строк, может полностью сломаться на больших данных. Оптимизацию нужно проверять не только на локальных тестах, но и на реальных объёмах.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣6👍4🤯1🍾1
В .NET долгое время одним из самых удобных инструментов для организации CQRS и разделения логики был MediatR, он помогал структурировать команды и запросы, разгружал API слой и снижал связанность кода. Многие проекты, особенно с архитектурой Vertical Slice, держались на нём годами.

Но в работе со сложными сценариями у MediatR есть нюанс. Из-за отвязки команд и обработчиков навигация по коду и отладка становятся менее очевидными, особенно когда один обработчик начинает вызывать другой.

Альтернатива, которая решает эти проблемы, — переход на простые ручные обработчики. Такой подход убирает лишнюю рефлексию и декораторы, упрощает трассировку, а IDE быстрее находит нужный участок кода.

Вот гайд как выстроить систему, где:

> Стартовая реализация использует MediatR, а затем заменяется на ручные обработчики

> Регистрация обработчиков происходит автоматически

> Уведомления обрабатываются без MediatR Notifications

> Общая функциональность (логирование, валидация, транзакции) подключается без лишней обвязки

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

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
5🤨1🍾1
В C# 16 разработчики планируют сосредоточиться на нескольких крупных направлениях:

Среди них — развитие unsafe, новый синтаксис для словарей, закрытые enum, улучшенный вывод типов и более удобное декларативное создание интерфейсов.

https://github.com/dotnet/csharplang/discussions/10276/

Как вам такой набор изменений?

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾4🌭2
Сегодня у меня для вас небольшая задачка.

Оба метода удаляют один товар и возвращают одинаковые HTTP-статусы, но…

Под капотом они работают совершенно по-разному.

Какую реализацию выбрали бы вы?

Сможете определить различия?

Пишите свои варианты решения в комментариях!

Приятного брейншторма! 🧠

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾21
Строки в C# кажутся простой темой — пока не становятся причиной:

нечитаемого кода
лишних аллокаций
скрытых ошибок при сравнении
некорректной валидации
неудобного форматирования многострочного текста

В своих проектах я придерживаюсь пяти правил:
1. Использую интерполяцию строк
2. Для большого количества конкатенаций применяю StringBuilder
3. Проверяю строки через string.IsNullOrWhiteSpace
4. Явно указываю StringComparison
5. Использую raw- или verbatim-строки

Меньше экранирования.
Меньше лишнего шума.
Более читаемый код.
Даже небольшие улучшения в работе со строками делают код безопаснее, чище и проще в поддержке.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
4🍌1😐1🍾1