Мы Создали Слой Кэша. PostgreSQL Показал, что Зря.
Пользователь открывает страницу свего тарифного плана, а видит старый. Он обновляет страницу, и всё исправляется. Наш показатель попадания в кэш 98%, а мы всё равно выглядели некомпетентными. В тот момент мы перестали рассматривать кэширование как функцию повышения производительности и стали рассматривать его как проблему истинности. Потому что система перестала быть медленной, зато она стала ненадёжной.
Что было дальше🤙
👉 @KodBlog
Пользователь открывает страницу свего тарифного плана, а видит старый. Он обновляет страницу, и всё исправляется. Наш показатель попадания в кэш 98%, а мы всё равно выглядели некомпетентными. В тот момент мы перестали рассматривать кэширование как функцию повышения производительности и стали рассматривать его как проблему истинности. Потому что система перестала быть медленной, зато она стала ненадёжной.
Что было дальше
Please open Telegram to view this post
VIEW IN TELEGRAM
Medium
We Built A Cache Layer. PostgreSQL Made It Embarrassing.
A user upgrades their plan and still sees the old one.
😁4👍2🍾2👎1
DataAnnotations против FluentValidationDataAnnotations тоже позволяют валидировать данные с проверкой в базе через кастомный атрибут + IUserRepository.FluentValidation обычно оказывается чище, слабее связан с остальным кодом и проще покрывается тестами.#dotnet #csharp
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🍾1
Хватит жонглировать разрозненными инструментами для JSON. 🧱
JSON-everything — это высокопроизводительный, соответствующий стандартам набор инструментов для Schema, Patch, Path и других задач — всё в рамках одной экосистемы .NET. Открытый исходный код, ориентирован на современные сценарии разработки.
https://hubs.li/Q04bsKZy0
👉 @KodBlog
JSON-everything — это высокопроизводительный, соответствующий стандартам набор инструментов для Schema, Patch, Path и других задач — всё в рамках одной экосистемы .NET. Открытый исходный код, ориентирован на современные сценарии разработки.
https://hubs.li/Q04bsKZy0
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - json-everything/json-everything: System.Text.Json-based support for all of your JSON needs.
System.Text.Json-based support for all of your JSON needs. - json-everything/json-everything
❤4🍾1
Забирай мой подход для упрощения управления потоками:
(начиная с .NET 9)
Вместо классического
Вместе с ним появился метод
Этот тип даёт более удобную синхронизацию потоков через свой API.
Оператор
В таком случае он использует новый API, а не классический механизм.
Смотри код ниже.
Что думаешь про это нововведение?
👉 @KodBlog
(начиная с .NET 9)
Вместо классического
System.Threading.Monitor в .NET 9 появился новый тип — System.Threading.Lock.Вместе с ним появился метод
Lock.EnterScope(), который создаёт эксклюзивную область и автоматически освобождает блокировку после выхода из блока кода.Этот тип даёт более удобную синхронизацию потоков через свой API.
Оператор
lock в C# умеет распознавать, когда целью блокировки выступает объект Lock.В таком случае он использует новый API, а не классический механизм.
Смотри код ниже.
Что думаешь про это нововведение?
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍4🤣3❤2👎1
This media is not supported in your browser
VIEW IN TELEGRAM
Cleanpilot — современная альтернатива CCleaner, написанная на C# / WinUI 3, полностью работающая на основе winapp2.ini
Публичная превью-версия уже доступна : https://github.com/builtbybel/Cleanpilot/
👉 @KodBlog
Публичная превью-версия уже доступна : https://github.com/builtbybel/Cleanpilot/
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍3🍾2
Большинство .NET-разработчиков в 2026 всё ещё копируют строки подключения между файлами appsettings.json.
В прошлом месяце у меня было 4 сервиса в одном решении. У каждого — своя строка подключения к PostgreSQL. Логирование настроено по-разному. Проверки состояния были только в двух.
Потом строка подключения изменилась. Я обновил 3 проекта. Про четвёртый забыл. Потратил 45 минут на отладку, пытаясь понять, почему один сервис падает с ошибками подключения, а остальные работают нормально.
В этот момент я перенёс всё на .NET Aspire.
➡️ Строки подключения? Определяются один раз в AppHost. Подставляются во все сервисы автоматически.
➡️ Логирование? Настраивается один раз в ServiceDefaults. Применяется ко всем сервисам.
➡️ Проверки состояния? Встроены. WaitFor() управляет порядком запуска.
➡️ Наблюдаемость? Трейсы, метрики и структурированные логи через OpenTelemetry. Без дополнительной стоимости.
«Но Aspire только для Azure». Нет. Я деплою в AWS. Aspire управляет локальной разработкой. Облачная платформа отвечает за продакшн. Это разные зоны ответственности.
«Но это добавляет сложность». Сложнее, чем поддерживать 5 разных конфигураций логирования для 5 сервисов? Сложнее, чем ловить рассинхронизацию строк подключения ночью?
Настоящая сложность — это связующий код, который вы пишете сейчас. Aspire его убирает.
Моё правило: 2+ сервиса с общей инфраструктурой — использовать Aspire. Меньше — можно обойтись без него.
👉 @KodBlog
В прошлом месяце у меня было 4 сервиса в одном решении. У каждого — своя строка подключения к PostgreSQL. Логирование настроено по-разному. Проверки состояния были только в двух.
Потом строка подключения изменилась. Я обновил 3 проекта. Про четвёртый забыл. Потратил 45 минут на отладку, пытаясь понять, почему один сервис падает с ошибками подключения, а остальные работают нормально.
В этот момент я перенёс всё на .NET Aspire.
«Но Aspire только для Azure». Нет. Я деплою в AWS. Aspire управляет локальной разработкой. Облачная платформа отвечает за продакшн. Это разные зоны ответственности.
«Но это добавляет сложность». Сложнее, чем поддерживать 5 разных конфигураций логирования для 5 сервисов? Сложнее, чем ловить рассинхронизацию строк подключения ночью?
Настоящая сложность — это связующий код, который вы пишете сейчас. Aspire его убирает.
Моё правило: 2+ сервиса с общей инфраструктурой — использовать Aspire. Меньше — можно обойтись без него.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👏3
Наш слон: собрал полноценный движок инференса LLM на C#/.NET 10. С нуля. 🐘
Не обёртка — нативная загрузка GGUF, токенизатор BPE, механизм внимания, KV-кэш, SIMD-векторизованные CPU-ядра, CUDA-бэкенд для GPU, API, совместимый с OpenAI.
Один разработчик, ~2 месяца, с использованием ИИ (без вайбкодинга). Первый превью-релиз уже доступен.
Подробнее: https://kokosa.dev/blog/2026/dotllm/ и https://dotllm.dev/
👉 @KodBlog
Не обёртка — нативная загрузка GGUF, токенизатор BPE, механизм внимания, KV-кэш, SIMD-векторизованные CPU-ядра, CUDA-бэкенд для GPU, API, совместимый с OpenAI.
Один разработчик, ~2 месяца, с использованием ИИ (без вайбкодинга). Первый превью-релиз уже доступен.
Подробнее: https://kokosa.dev/blog/2026/dotllm/ и https://dotllm.dev/
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13❤5👏3👍1
C#-приложения с файловой моделью и поддержкой нескольких файлов — кому-то нужно? Появится в .NET 10.0.300 и будущих превью .NET 11
@dotnet
https://github.com/DamianEdwards/runfile/compare/main...include-directive
👉 @KodBlog
@dotnet
https://github.com/DamianEdwards/runfile/compare/main...include-directive
Please open Telegram to view this post
VIEW IN TELEGRAM
😁3
.NET 11 Preview 3 приносит обновления для
— Улучшения поддержки объединённых типов в средах разработки (полифилы всё ещё требуются)
—`dotnet run -e` (встроенные переменные окружения)
— Файловые приложения → поддержка нескольких файлов (
— Улучшения
и другое...
👉 @KodBlog
dotnet run и развитие поддержки объединённых типов — Улучшения поддержки объединённых типов в средах разработки (полифилы всё ещё требуются)
—`dotnet run -e` (встроенные переменные окружения)
— Файловые приложения → поддержка нескольких файлов (
#:include)— Улучшения
dotnet watch с интеграцией Aspireи другое...
Please open Telegram to view this post
VIEW IN TELEGRAM
Microsoft News
.NET 11 Preview 3 is now available!
Find out about the new features in .NET 11 Preview 3 across the .NET runtime, SDK, libraries, ASP.NET Core, .NET MAUI, C#, Entity Framework Core, container images, and more!
🍾1
.NET 11 Preview 3 приносит важное обновление в EF Core:
Теперь можно выполнять запросы к JSON в SQL Server напрямую из LINQ
❌ Раньше: ручной SQL + JSON_VALUE
✅ Теперь: JsonContains
Меньше кода, чище и проще сопровождать.
👉 @KodBlog
Теперь можно выполнять запросы к JSON в SQL Server напрямую из LINQ
Меньше кода, чище и проще сопровождать.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤3😁3🍾3🤔1
.NET 10 включает dnx — по сути аналог npx для .NET.
Скачивает и запускает локальный MCP-сервер. Установка не требуется.
Работает с MCP-серверами для NuGet, Azure, Bicep, Power Platform. Добавляешь в mcp.json — и готово.
Тихое, но важное изменение для AI-инструментария.
👉 @KodBlog
dnx NuGet.Mcp.Server --yes
Скачивает и запускает локальный MCP-сервер. Установка не требуется.
Работает с MCP-серверами для NuGet, Azure, Bicep, Power Platform. Добавляешь в mcp.json — и готово.
Тихое, но важное изменение для AI-инструментария.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3🍾2
Отличная статья о том, как многие инициативы в C#, dotnet и aspnetcore за последние годы складываются в единую историю: https://makarchie.com/posts/csharp-that-looks-like-go-file-based-apps/
👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
makarchie Tech
C# That Looks Like Go: Building a Web API Without a .csproj
A walkthrough of building a real ASP.NET Core web API as a .NET 11 file-based app. No .csproj, no .sln, publishes to a ~30 MB native AOT binary. Includes the EF Core migrations workaround.
🍾3
CQRS ≠ MediatR.
Перестаньте смешивать CQRS и MediatR.
То, что вы используете MediatR, не означает, что у вас реализован CQRS.
CQRS — это про разделение операций чтения и записи, часто с разными моделями, стратегиями хранения и иногда с разными хранилищами данных.
MediatR — это библиотека для диспетчеризации сообщений внутри процесса. Она удобна для организации команд и запросов, но это не фреймворк CQRS.
Можно использовать MediatR в архитектуре, построенной по CQRS.
Но не стоит считать, что одно автоматически означает другое.
Сначала разберитесь в различии, прежде чем внедрять паттерн или инструмент.
👉 @KodBlog
Перестаньте смешивать CQRS и MediatR.
То, что вы используете MediatR, не означает, что у вас реализован CQRS.
CQRS — это про разделение операций чтения и записи, часто с разными моделями, стратегиями хранения и иногда с разными хранилищами данных.
MediatR — это библиотека для диспетчеризации сообщений внутри процесса. Она удобна для организации команд и запросов, но это не фреймворк CQRS.
Можно использовать MediatR в архитектуре, построенной по CQRS.
Но не стоит считать, что одно автоматически означает другое.
Сначала разберитесь в различии, прежде чем внедрять паттерн или инструмент.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤4🍾1
Два списания одновременно с одного и того же банковского счёта — что может пойти не так?
Если плохо управлять конкурентным доступом, последствия могут быть критичными:
-» дублирующиеся списания
-» потеря денег💸
Начиная с .NET 9, используйте
#dotnet #csharp
👉 @KodBlog
Если плохо управлять конкурентным доступом, последствия могут быть критичными:
-» дублирующиеся списания
-» потеря денег
Начиная с .NET 9, используйте
Lock и контролируйте конкурентный доступ.#dotnet #csharp
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10🥴4👎2🍾1
В EF Core методы
Они лишь помечают сущность как новую для последующей вставки.
Сам
#dotnet #efcore
👉 @KodBlog
Add() и AddAsync() не выполняют вставку в БД.Они лишь помечают сущность как новую для последующей вставки.
Сам
INSERT происходит при вызове SaveChanges() или SaveChangesAsync().AddAsync() имеет смысл только в специфичных кейсах, например с HiLo, когда EF Core может получить идентификатор до сохранения.#dotnet #efcore
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🍾2
Вот насколько просто создать HTTP-сервер с помощью минимального API в .NET на C#.
Ты уже знал об этом?
👉 @KodBlog
Ты уже знал об этом?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🍾2
Please open Telegram to view this post
VIEW IN TELEGRAM
Andrew Lock | .NET Escapades
Removing byte[] allocations in .NET Framework using ReadOnlySpan<T>
In this post I describe how to remove static byte[] allocations, even on .NET Framework, by using Span<T>, look at the associated IL, and discuss the risks
👍6❤1🍾1
This media is not supported in your browser
VIEW IN TELEGRAM
90% разработчиков используют LINQ неправильно… и теряют производительность
Если вы повторяете вычисления внутри запроса, вы делаете двойную работу
Используйте
✅ одно вычисление
✅ + производительность
✅ + читаемость
👉 @KodBlog
Если вы повторяете вычисления внутри запроса, вы делаете двойную работу
Используйте
let и оптимизируйте всёPlease open Telegram to view this post
VIEW IN TELEGRAM
👍10🤯3❤2🍾1
Кэширование — одна из тех вещей, где каждый .NET-разработчик уверен, что разобрался.
Пока не ломается прод.
Большинство команд, с которыми я работал, используют IMemoryCache или Redis и на этом останавливаются. У обоих есть реальные проблемы, которые проявляются только на масштабе.
Потом в .NET 9 появился HybridCache и тихо закрыл то, что обычно костылят вручную.
Разберём по порядку.
𝗜𝗠𝗲𝗺𝗼𝗿𝘆𝗖𝗮𝗰𝗵𝗲
Очень быстрый. Живёт внутри приложения, чтение практически бесплатное.
Но как только появляется больше одного инстанса — начинаются рассинхроны. Каждый сервер держит свою копию. Пользователь попадает на сервер A — получает свежие данные. Следующий запрос уходит на сервер B — получает устаревшие. Баги, которые всплывают только в проде.
𝗥𝗲𝗱𝗶𝘀 (или любой распределённый кэш)
Общий для всех инстансов. Проблему консистентности закрывает.
Но каждое чтение — это сетевой вызов плюс сериализация с обеих сторон. Быстрее базы, но уже не уровень in-memory.
𝗛𝘆𝗯𝗿𝗶𝗱𝗖𝗮𝗰𝗵𝗲
Идея простая: использовать оба слоя.
Сначала проверяется память (L1). Если есть — возврат мгновенно.
Если нет — проверяется Redis (L2). Если есть — вернуть и прогреть L1.
Если нет — запрос в базу, запись в оба слоя, возврат.
Скорость памяти для горячих данных. Консистентность распределённого кэша для остального.
𝗣𝗿𝗼𝗯𝗹𝗲𝗺𝗮, о которой редко говорят
Часто ловит даже опытные команды.
Представим: популярный ключ протух. В этот же момент приходит 500 запросов на этот ключ. Все 500 промахиваются по кэшу. Все 500 одновременно идут в базу.
База ложится. Локально почти не воспроизводится.
Обычно это закрывают через SemaphoreSlim и ретраи. HybridCache решает это из коробки: только один запрос идёт за данными, остальные ждут тот же результат.
𝗣𝗼𝗷𝗲𝗺𝘂 это становится дефолтом
• Работает без Redis: старт с in-memory, потом подключение распределённого слоя без переписывания
• Инвалидация по тегам встроена — не нужно вручную трекать ключи
• Защита от конкурентных промахов уже есть
• Единый API — GetOrCreateAsync закрывает весь флоу
• Поставляется вместе с .NET 9
Если до сих пор пишется cache-aside логика с ручными локами и ретраями — HybridCache уже покрывает этот сценарий.
👉 @KodBlog
Пока не ломается прод.
Большинство команд, с которыми я работал, используют IMemoryCache или Redis и на этом останавливаются. У обоих есть реальные проблемы, которые проявляются только на масштабе.
Потом в .NET 9 появился HybridCache и тихо закрыл то, что обычно костылят вручную.
Разберём по порядку.
𝗜𝗠𝗲𝗺𝗼𝗿𝘆𝗖𝗮𝗰𝗵𝗲
Очень быстрый. Живёт внутри приложения, чтение практически бесплатное.
Но как только появляется больше одного инстанса — начинаются рассинхроны. Каждый сервер держит свою копию. Пользователь попадает на сервер A — получает свежие данные. Следующий запрос уходит на сервер B — получает устаревшие. Баги, которые всплывают только в проде.
𝗥𝗲𝗱𝗶𝘀 (или любой распределённый кэш)
Общий для всех инстансов. Проблему консистентности закрывает.
Но каждое чтение — это сетевой вызов плюс сериализация с обеих сторон. Быстрее базы, но уже не уровень in-memory.
𝗛𝘆𝗯𝗿𝗶𝗱𝗖𝗮𝗰𝗵𝗲
Идея простая: использовать оба слоя.
Сначала проверяется память (L1). Если есть — возврат мгновенно.
Если нет — проверяется Redis (L2). Если есть — вернуть и прогреть L1.
Если нет — запрос в базу, запись в оба слоя, возврат.
Скорость памяти для горячих данных. Консистентность распределённого кэша для остального.
𝗣𝗿𝗼𝗯𝗹𝗲𝗺𝗮, о которой редко говорят
Часто ловит даже опытные команды.
Представим: популярный ключ протух. В этот же момент приходит 500 запросов на этот ключ. Все 500 промахиваются по кэшу. Все 500 одновременно идут в базу.
База ложится. Локально почти не воспроизводится.
Обычно это закрывают через SemaphoreSlim и ретраи. HybridCache решает это из коробки: только один запрос идёт за данными, остальные ждут тот же результат.
𝗣𝗼𝗷𝗲𝗺𝘂 это становится дефолтом
• Работает без Redis: старт с in-memory, потом подключение распределённого слоя без переписывания
• Инвалидация по тегам встроена — не нужно вручную трекать ключи
• Защита от конкурентных промахов уже есть
• Единый API — GetOrCreateAsync закрывает весь флоу
• Поставляется вместе с .NET 9
Если до сих пор пишется cache-aside логика с ручными локами и ретраями — HybridCache уже покрывает этот сценарий.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🍾2