Библиотека шарписта | C#, F#, .NET, ASP.NET
21.9K subscribers
2.83K photos
41 videos
85 files
5.24K links
Все самое полезное для C#-разработчика в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/b60af5a4

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead
Download Telegram
🤩 Copilot Studio перешёл на .NET 10 и стал быстрее

Microsoft Copilot Studio обновил свой WebAssembly-движок с .NET 8 до .NET 10.

Что изменилось

Сам переход свёлся к обновлению <TargetFramework> на net10.0 и проверке совместимости зависимостей. Но за этим стоят три заметных улучшения в .NET 10 для WASM.

Раньше WASM-приложениям приходилось вручную переименовывать файлы с добавлением SHA256-хеша для сброса кэша. Команда Copilot Studio использовала для этого отдельный PowerShell-скрипт, который читал манифест blazor.boot.json и прогонял каждый файл.

В .NET 10 fingerprint встроен в имена файлов при публикации, а проверка целостности работает из коробки через dotnet.js. Скрипт удалили, аргумент integrity в загрузчике ресурсов убрали.

Если вы загружаете .NET WASM-рантайм внутри WebWorker, при инициализации укажите dotnetSidecar = true.

После AOT-компиляции методов в WebAssembly исходный IL-код больше не нужен в рантайме. В .NET 8 эта настройка существовала, но была выключена. Теперь IL автоматически вырезается из опубликованных сборок.

Выигрыш в рантайме перекрывает рост размера пакета. Холодный запуск стал быстрее примерно на 20%. Повторные вызовы ускорились на ~5%. Больше всего выигрывают сложные агенты с большим объёмом AOT-кода.

Как обновиться

Обновите <TargetFramework> на net10.0 и подтяните свежие версии пакетов Microsoft.AspNetCore.*, Microsoft.Extensions.* и System.*. Если у вас были скрипты для переименования ресурсов или ручная проверка integrity, их можно удалить.

Для автоматизации миграции Microsoft предлагает GitHub Copilot app modernization for .NET, который анализирует решение, планирует апгрейд и применяет изменения.

➡️ Блог разработчиков

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🛠 C# для микроконтроллеров

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

.NET nanoFramework меняет этот сценарий: код пишется на C#, отлаживается в Visual Studio, а запускается прямо на MCU.

Что это такое

.NET nanoFramework это открытая платформа для запуска C#-кода на микроконтроллерах с ограниченными ресурсами. Это не эмуляция и не кросс-компиляция в C. Прошивка nanoFramework устанавливается на устройство, и уже она выполняет скомпилированный C#-код.

Как выглядит код

Пример мигания светодиодом на ESP32:
using System.Device.Gpio;
using System.Threading;

var gpio = new GpioController();
gpio.OpenPin(2, PinMode.Output);

while (true)
{
gpio.Write(2, PinValue.High);
Thread.Sleep(500);
gpio.Write(2, PinValue.Low);
Thread.Sleep(500);
}


API намеренно выровнено с .NET IoT, поэтому код, написанный для Raspberry Pi через System.Device.Gpio, во многом переносится на MCU без серьёзных правок.

Инструментарий

Работа идёт в Visual Studio с бесплатным расширением nanoFramework. Поддерживается полноценный отладчик прямо на железе: точки останова, пошаговое выполнение, просмотр переменных. Пакеты распространяются через NuGet.

Где применяется

Среди реальных кейсов — мониторинг нефтяных скважин, удалённое управление солнечными электростанциями, промышленные измерительные системы.

➡️ Репозиторий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥202😁2😢1
🧑‍💻 HTTP Referer в ASP.NET Core

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

Это стандартный механизм веба, и он уже встроен в HTTP. Никаких query string добавлять не нужно.

Как читать Referer на сервере

В ASP.NET Core заголовок доступен через Request.Headers:
app.MapGet("/page", (HttpContext ctx) =>
{
var referer = ctx.Request.Headers["Referer"].ToString();

if (string.IsNullOrEmpty(referer))
return Results.Ok("Прямой переход или Referer скрыт");

return Results.Ok($"Пришли с: {referer}");
});


В контроллерах то же самое:
[HttpGet]
public IActionResult Index()
{
var referer = Request.Headers["Referer"].ToString();
// использование по необходимости
return View();
}


Как управлять тем, что браузер отправляет


За это отвечает заголовок Referrer-Policy. Он задаётся на сервере и говорит браузеру, сколько информации об источнике передавать при переходах.

Основные значения:

no-referrer — браузер не отправляет Referer вообще.

origin — передаёт только домен без пути: https://example.com/ вместо https://example.com/some/page.

strict-origin-when-cross-origin — полный URL при переходах в рамках одного домена, только origin при переходах на другой домен, ничего при переходе с HTTPS на HTTP.

unsafe-url — всегда передаёт полный URL, включая path и query. Название говорит само за себя.

Настройка в ASP.NET Core

Через middleware:
app.Use(async (ctx, next) =>
{
ctx.Response.Headers["Referrer-Policy"] = "strict-origin-when-cross-origin";
await next();
});


Или через app.UseHsts() в связке с пакетом NWebsec.AspNetCore.Middleware:
app.UseReferrerPolicy(opts => opts.StrictOriginWhenCrossOrigin());


Когда Referer может отсутствовать


Браузер не отправляет заголовок в нескольких случаях: прямой ввод URL, переход из локального файла, политика no-referrer на стороне отправителя, переход с HTTPS на HTTP.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51
👨‍💻 Управляем буферизацией результатов

Когда вы используете AsParallel(), PLINQ по умолчанию буферизует результаты перед тем, как отдать их вызывающему коду. Для небольших коллекций это незаметно.

На больших объёмах данных стратегия буферизации напрямую влияет на задержку и пропускную способность.

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

Как использовать:
var results = items
.AsParallel()
.WithMergeOptions(ParallelMergeOptions.NotBuffered)
.Select(ProcessItem)
.ToList();


Три режима работы

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

FullyBuffered — все результаты сначала собираются в памяти, потом отдаются целиком. Полезно, когда важен порядок или когда вы всё равно ждёте полного завершения (например, при сортировке). Даёт максимальную пропускную способность, но первый элемент вы получите только после обработки последнего.

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

Когда это пригодится

Если вы обрабатываете тысячи элементов и хотите показывать прогресс в реальном времени, NotBuffered сократит время до первого результата. Если же вам нужен отсортированный вывод или полная выборка перед следующим шагом, FullyBuffered будет эффективнее.

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

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
5🥱1
⭐️ Шаблоны проектов теперь работают из командной строки

Microsoft выпустила набор open-source шаблонов для WinUI, которые позволяют создавать приложения через dotnet new без Visual Studio. Пока это preview, но уже можно пользоваться.

Зачем это нужно

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

Как начать

Устанавливаем шаблоны и создаём приложение:
dotnet new install Microsoft.WindowsAppSDK.WinUI.CSharp.Templates
dotnet new winui-navview -n MyApp
cd MyApp
dotnet run


dotnet run сразу собирает и запускает упакованное приложение с package identity. Не нужен ни Add-AppxPackage, ни ручная регистрация. Под капотом работает WinApp CLI из пакета Microsoft.Windows.SDK.BuildTools.WinApp.

Какие шаблоны доступны

Все шаблоны следуют Windows app silhouettes и Fluent Design. В комплекте обновлённая иконка приложения с поддержкой светлой и тёмной темы.

• Шаблон Blank (dotnet new winui) создаёт чистый проект с современным title bar и Fluent-стилями из коробки.

• Шаблон NavigationView (dotnet new winui-navview) даёт готовую структуру с боковой навигацией и несколькими страницами. Подходит для большинства приложений.

• Шаблон TabView (dotnet new winui-tabview) генерирует интерфейс на вкладках с поддержкой добавления, удаления и перетаскивания табов.

• Шаблон MVVM (dotnet new winui-mvvm) включает базовую структуру Model-View-ViewModel с рабочим примером на CommunityToolkit.MVVM.

Помимо шаблонов проектов, есть item-шаблоны для добавления отдельных элементов в существующий проект. Например, чтобы добавить ContentDialog:
dotnet new winui -n MyApp
cd MyApp
dotnet new winui-dialog -n MyDialog


Посмотреть все доступные шаблоны можно командой:
dotnet new list winui


Что дальше

Шаблоны появятся и в Visual Studio 2026. Пока можно ставить из CLI и использовать с любым редактором. Шаблоны в open-source, фидбек и контрибьюции принимаются на GitHub.

➡️ Источник

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🤔1🥱1
🔥 Знакомьтесь с экспертом Proglib.academy: Эмиль Сатаев

Эмиль — эксперт с 8-летним опытом в разработке, который специализируется на внедрении LLM и агентных подходов в реальные коммерческие сервисы. Он точно знает, как проектировать архитектуру так, чтобы ИИ-функции работали стабильно в связке с внешними системами.

🏃‍♀️ Уже 14 мая Эмиль проведет открытый вебинар!

Обсудим самую «больную» тему: «Почему AI-продукты на базе LLM ломаются и как сделать, чтобы работало».

🗓 Когда: 14 мая в 19:00 (Мск)

Почему Эмиля стоит послушать:

🟣 8+ лет в разработке (Backend и Frontend)
Прошел путь от фулстека до Backend Platform Developer в SMIT.Studio.


🟣 Международный исследовательский опыт
Работал исследователем в Институте ИИ НИУ ВШЭ и в Национальном университете Сингапура (NUS).


🟣 Преподаватель-практик
Ведет семинары в НИУ ВШЭ, в том числе по проектированию и разработке агентских систем.


🟣 Мастер интеграции AI в Backend
Его главная суперсила — умение правильно встраивать LLM через API, выстраивать workflow и агентную логику в сложных распределенных системах.


🔗 Зарегистрироваться на вебинар
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱1
⭐️ .NET 11 Preview 4

Microsoft выпустили четвёртый превью .NET 11. Релиз затрагивает рантайм, SDK, библиотеки, ASP.NET Core, MAUI, EF Core и C#.

Process API наконец стал удобным

System.Diagnostics.Process получил набор методов, которых не хватало годами. Раньше для простого «запустить процесс и прочитать stdout» приходилось вручную подписываться на OutputDataReceived, создавать TaskCompletionSource и следить за жизненным циклом. Теперь это одна строка.

Process.RunAndCaptureTextAsync запускает процесс и возвращает stdout, stderr и exit code:
var result = await Process.RunAndCaptureTextAsync(
"git", ["status", "--porcelain"]);

Console.WriteLine(result.StandardOutput);
Console.WriteLine($"exit code: {result.ExitStatus.ExitCode}");


Process.StartAndForget запускает дочерний процесс без ожидания. ProcessStartInfo.StartDetached отвязывает процесс от терминала, чтобы он жил после закрытия консоли. На Windows есть обратный вариант: KillOnParentExit убивает дочерний процесс, когда родительский завершается.

ProcessStartInfo.InheritedHandles позволяет передать дочернему процессу только конкретные OS-хендлы вместо поведения «всё или ничего» через UseShellExecute = false.

На Linux и macOS убрали лишние аллокации при запуске процессов. ProcessName и ToString больше не создают полный снапшот ProcessInfo, а формирование envp/argv обходится без промежуточных managed-строк.

Span-based сжатие для Deflate, ZLib и GZip

В System.IO.Compression добавили API на основе Span<byte> для Deflate, ZLib и GZip. По форме они повторяют BrotliEncoder/BrotliDecoder и Zstandard-примитивы. Можно сжимать и распаковывать буферы без создания Stream.
using ZLibEncoder encoder = new();
OperationStatus status = encoder.Compress(
source, destination, out int bytesConsumed,
out int bytesWritten, isFinalBlock: true);

Полезно для протокольных парсеров, лог-шипперов и middleware, которые и так работают со спанами.

Hex-формат для float и double

double, float и Half теперь умеют форматироваться и парситься в hex-представлении IEEE-754. Формат сохраняет каждый бит значения, что критично для golden-file тестов и интеропа с C/C++ printf("%a", ...).
double value = Math.PI;
string hex = value.ToString("X"); // "0X1.921FB54442D18P+1"
double round = double.Parse(hex, NumberStyles.HexFloat);
Console.WriteLine(round == value); // True


System.Text.Json теперь понимает F# discriminated unions

Сериализатор научился работать с F# discriminated unions без кастомных конвертеров. Если у вас F#-типы на бэкенде и C#-консьюмеры, теперь всё работает из коробки.

Source generator тоже подтянули: generic-обёртки аксессоров правильно прокидывают constraints от исходного типа, а для доступа к приватным членам используется [UnsafeAccessor] вместо рефлексии.

Рантайм-библиотеки скомпилированы с runtime-async

Стандартные библиотеки рантайма теперь собираются с включённым runtime-async. Это внутренняя оптимизация JIT, которая уменьшает overhead async/await на горячих путях.

ASP.NET Core

В генерируемые OpenAPI-документы добавили поддержку HTTP-метода QUERY (RFC 9110). Для Blazor появился атрибут SupplyParameterFromTempData и серверная пауза Blazor Server circuit. Вместе с SDK теперь идёт шаблон MCP Server, так что создать MCP-совместимый бэкенд можно через dotnet new.

SDK
 
dotnet watch получил выбор устройства для .NET MAUI и мобильных проектов. Fish shell теперь поддерживает автодополнение наравне с Bash, Zsh и PowerShell. CLI-телеметрия переехала с Application Insights на OpenTelemetry.

➡️ Полный список изменений

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍4
🎂 Подборка вакансий для шарпистов

.NET Developer (Backend) Middle — до 6 000 $ и удалёнка

Middle .NET разработчик — от 140 000 ₽ в офис в Краснодаре

C# разработчик — от 200 000 ₽, офис в Санкт-Петербурге

➡️ Еще больше топовых вакансий — в нашем канале C# Jobs

🐸 Библиотека шарписта
Please open Telegram to view this post
VIEW IN TELEGRAM
Talanto.work - сайт для всех, кто ищет работу в IT.

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

Просто настройте фильтры у нас на сайте и получайте уведомления в телегу, как только вакансия вышла.

Например: все вакансии C#

На talanto.work собрано 28.000+ вакансий из разных .ru и иностранных сайтов: разработка, QA, аналитика, DevOps, продакт, дизайн, менеджмент и другие IT/Digital-направления.

Более 1700 вакансий за последний месяц из телеграм каналов.

Что еще есть на сайте:

🟠 Фильтры для нормального поиска
Можно искать по стеку, грейду, зарплате, стране, формату работы, релокации и типу занятости.

🟠 Разбор резюме
Загружаете CV и получаете конкретные рекомендации: что улучшить, какие навыки добавить, где слабая структура и что может мешать пройти ATS.

🟠Проверка соответствия вакансии и резюме
Рядом с вакансией всегда есть кнопочка узнать соответствие, насколько ваш профиль ей подходит. Сервис покажет процент совпадения, сильные стороны и пробелы в резюме

🟠Сопроводительное письмо за 10 секунд
Вставляете вакансию и получаете персональное письмо под конкретную компанию и роль, а не шаблон “прошу рассмотреть мою кандидатуру”.

🟠Уведомления в Telegram
Задаёте фильтры один раз и бот присылает новые подходящие вакансии прямо в Telegram.

Поиск работы в IT сейчас и так сложный. Мы хотим, чтобы вы тратили меньше времени на листание сайтов и больше на точные отклики туда, где у вас реально есть шанс.

✈️ 28.000+ вакансий
🟢Бот с уведомлениями о ваших вакансиях: @TalantoWorkBot
🟢Написать сопровод
🟢Разобрать резюме
🟢Проверить соответствие резюме вакансиям

Реклама. Киренкина Марина Дмитриевна, ИНН 345702417736. Erid 2VtzqvLKkMm
Please open Telegram to view this post
VIEW IN TELEGRAM
🔒 Майское обновление безопасности .NET и .NET Framework

Microsoft выпустила сервисные обновления для .NET 10.0.8, .NET 9.0.16, .NET 8.0.27 и .NET Framework.

Закрыты четыре уязвимости: две связаны с повышением привилегий (CVE-2026-32177, CVE-2026-35433), одна с подменой данных (CVE-2026-32175) и одна с отказом в обслуживании (CVE-2026-42899).

CVE-2026-32177 затрагивает все поддерживаемые версии, включая .NET Framework 3.5, 4.6.2, 4.7, 4.7.2, 4.8 и 4.8.1.

Остальные три CVE касаются только .NET 8, 9 и 10. Помимо патчей безопасности, в релиз вошли и обычные багфиксы.

➡️ Подробности

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
5😁2
✏️ Async/Await в C# — шпаргалка

➡️ Что такое Task

Task — это обещание, что какое-то событие произойдёт в будущем. Не результат, а именно обещание.

Task<T> — то же самое, но с результатом типа T. Когда задача завершится, значение станет доступно.

Задача считается завершённой, когда событие произошло или значение получено. Проверить это можно через IsCompleted или Status.

➡️ Как дождаться результата

Правильно — асинхронно:

await task — отпускает поток, пока задача не завершится. Поток свободен, приложение не зависает.

ContinueWith(action) — задача сама вызовет ваш колбэк, когда завершится. Полезно, если нужно выстроить цепочку без await.

Неправильно — синхронно:

task.Wait() и task.Result блокируют текущий поток до завершения задачи. Это неэффективно, ведь поток простаивает и опасно: риск дедлока в UI и ASP.NET-контекстах.

Единственное исключение: вызывать Wait или Result на уже завершённой задаче безопасно и дёшево — результат уже есть, блокировки не будет.

➡️ Что делает async

async — это флаг для компилятора: «в этом методе может встретиться await, подготовь конечный автомат». Не более того.

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

async не запускает код в фоновом потоке. Если нужен фоновый поток — используйте Task.Run.

➡️ Что делает await

await — точка, в которой метод «разрезается» на до и после. Если задача ещё не завершена, управление возвращается вызывающему коду. Когда задача завершится — выполнение продолжится с того же места.

Без await ключевое слово async ничего не делает.

➡️ Частые ошибки

Вызов .Result или .Wait() в UI-потоке — дедлок. UI-поток заблокирован ожиданием, а задача не может завершиться, потому что ей нужен тот же UI-поток.

async void — допустим только для обработчиков событий. В остальных случаях используйте async Task. Исключения из async void невозможно поймать извне.

Забыли await — задача запустится, но никто не дождётся её завершения. Ошибки внутри неё потеряются молча.

async без await — компилятор предупредит, и правильно сделает. Метод синхронный, а обёртка в Task создаёт ложные ожидания у вызывающего кода.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥196👍6🤔1🥱1
👨‍💻 .NET MAUI переезжает на CoreCLR в .NET 11

Начиная с .NET 11 Preview 4, все приложения .NET MAUI на Android, iOS и Mac Catalyst по умолчанию работают на CoreCLR. Mono больше не является рантаймом по умолчанию для мобильных платформ.

Это значит, что мобильные приложения теперь крутятся на том же рантайме, что и ASP.NET Core, Azure-сервисы и десктопные приложения.

Что было раньше

До .NET 11 мобильная часть .NET MAUI работала на Mono. Серверные, облачные и десктопные приложения уже давно использовали CoreCLR.

Два разных рантайма означали разное поведение JIT, разные характеристики сборщика мусора, разный инструментарий диагностики и разные баги. Теперь эта разница уходит.

Mono обеспечивал работу .NET на мобильных платформах больше 15 лет. MonoTouch принёс C# на iPhone в 2009 году, MonoDroid появился для Android. На Mono построены Unity, Avalonia UI, Uno Platform, MonoGame и Godot.

Переход на CoreCLR не означает конец Mono. Blazor WebAssembly по-прежнему использует Mono, и в .NET 11 это не меняется.

Зачем переходить на CoreCLR

Унификация рантайма. Один рантайм для всех платформ означает единый набор инструментов и предсказуемое поведение. Не нужно держать в голове различия между Mono и CoreCLR.

Производительность. CoreCLR приносит на мобильные платформы tiered JIT compilation, ReadyToRun (R2R) прекомпиляцию и Profile-Guided Optimization (PGO). В Preview 4 уже включены partial R2R по умолчанию и встроенные PGO-профили. Стартап базового dotnet new maui приложения стал заметно быстрее.

NativeAOT. CoreCLR является основой для NativeAOT-компиляции. С переходом на CoreCLR открывается путь к NativeAOT на Android. На iOS и Mac Catalyst NativeAOT развивает уже существующую AOT-компиляцию, но с более унифицированным тулчейном.

Что с производительностью на практике

Для простых приложений стартап стал быстрее. Но сообщество уже сообщает о регрессиях в сложных приложениях на Android. Время запуска или размер приложения могут увеличиться. На iOS команда успешно прошла ревью App Store.

Из поддерживаемых архитектур убраны Android x86, Android API 23 и ниже, а также embedding APIs. Поддержка Android arm32 пока под вопросом.

Как откатиться на Mono

Если что-то пошло не так, можно временно вернуть Mono. Добавьте в файл проекта:
<PropertyGroup>
<UseMonoRuntime>true</UseMonoRuntime>
</PropertyGroup>


Работает для Android, iOS и Mac Catalyst. Опция доступна на протяжении всего сервисинга .NET 11.

Диагностика

Теперь на мобильных платформах работают стандартные инструменты .NET-диагностики: dotnet-trace и dotnet-counters. Те же инструменты, что вы используете на сервере и десктопе, теперь доступны для Android и iOS/Mac Catalyst.

Как попробовать

Установите .NET 11 Preview 4 SDK и workload:
dotnet workload install maui


Соберите приложение с таргетом net11.0-android, net11.0-ios или net11.0-maccatalyst и проверьте старт, размер пакета и общую работоспособность. Если нашли проблему, заводите issue в dotnet/android или dotnet/macios.

GA-релиз запланирован на ноябрь 2026, и фидбек из превью напрямую влияет на то, что будет исправлено.

➡️ Блог разработчиков

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
13👍2🤩1
🔄 Process API в .NET 11: большое обновление

System.Diagnostics.Process получил крупнейшее обновление за годы в .NET 11 Preview 4.

Чтение вывода без дедлоков

При перенаправлении stdout и stderr пайпы имеют ограниченный буфер. Последовательное чтение приводит к взаимной блокировке. Раньше нужно было вручную организовывать параллельное чтение. Теперь одна строка:
var output = Process.RunAndCaptureText("dotnet", ["--help"]);


Также есть ReadAllLinesAsync для построчного чтения и Process.Run когда вывод не нужен.

Контроль хэндлов

ProcessStartInfo.InheritedHandles указывает, какие хэндлы наследует дочерний процесс. Предотвращает утечку и удваивает пропускную способность параллельного запуска на Windows. Стандартные хэндлы можно перенаправить на файл, пайп или null.

Жизненный цикл

KillOnParentExit убивает дочерний процесс при завершении родителя, включая краши. StartDetached запускает процесс, переживающий родителя. StartAndForget возвращает PID и освобождает ресурсы.

Производительность

Запуск на Apple Silicon ускорен до 98x (posix_spawn). Параллельный запуск на Windows быстрее в 1.8x. Аллокации на Unix сокращены на 30–50%. NativeAOT с SafeProcessHandle до 32% меньше.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
3👏1
🤔 Вопрос с собеседования по C#

Как работают асинхронные делегаты и зачем они нужны?


Если вы думаете про async/await — это совсем другая история. Здесь механизм старше и ближе к ручному управлению потоками.

Попробуйте сформулировать ответ сами, а потом сверьтесь 👇

➡️ Ответ

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41
🛠 Не баг, а сигнал от пайплайна

Backpressure — механизм, через который консьюмер говорит продюсеру «притормози». TCP делает это с 70-х. Вопрос не нужен ли он, а какой именно.

System.Threading.Channels

В .NET есть System.Threading.Channels — асинхронная труба между продюсером и консьюмером. Канал бывает bounded или unbounded. Этот выбор определяет стратегию backpressure.

Drop

Данные живут секунды (телеметрия, тикеры). Важно последнее, а не каждое.
Channel.CreateBounded<SensorReading>(
new BoundedChannelOptions(500)
{ FullMode = BoundedChannelFullMode.DropOldest });

Продюсер не блокируется, консьюмер не голодает. Цена — потеря данных. Для аудита неприемлемо, для дашборда — осознанный выбор.

Buffer

Каждый элемент важен, консьюмер не успевает.
Channel.CreateUnbounded<OrderEvent>(
new UnboundedChannelOptions { SingleReader = true });

Unbounded-канал растёт, пока процесс не упрётся в память. Честная версия — «буфер с бюджетом». Внешний брокер (Kafka, RabbitMQ) или мониторинг глубины очереди. Если reader.Count растёт и не выравнивается — память не поможет.

Throttle

Продюсер может замедлиться. ETL-джоб не пострадает от лишних 200 мс.
Channel.CreateBounded<DataRecord>(
new BoundedChannelOptions(1000)
{ FullMode = BoundedChannelFullMode.Wait });

Когда канал полон, WriteAsync ждёт освобождения слота. Пайплайн работает на скорости самого медленного участника. Цена — latency.

Как выбирать

Drop — стабильность ценой полноты данных.
Buffer — полнота ценой памяти. Без мониторинга это бомба.
Throttle — полнота и стабильность ценой latency.

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

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
👍73💯2
🆚 EF Core vs Dapper — новые фичи EF закрывают разрыв

EF Core и Dapper решают пересекающиеся, но не одинаковые задачи. С каждым релизом EF Core сокращает отставание по производительности, но у Dapper по-прежнему есть своя ниша.

Что нового в EF Core

Compiled queries убирают overhead на трансляцию повторяющихся запросов.
private static readonly Func<AppDb, Guid, Task<UserDto?>> GetById =
EF.CompileAsyncQuery((AppDb db, Guid id) =>
db.Users.AsNoTracking()
.Where(u => u.Id == id)
.Select(u => new UserDto(u.Id, u.Email))
.FirstOrDefault());


ExecuteUpdateAsync / ExecuteDeleteAsync позволяют делать set-based операции без материализации сущностей.
await db.Orders
.Where(o => o.Status == "Pending" && o.CreatedAtUtc < cutoff)
.ExecuteUpdateAsync(s =>
s.SetProperty(o => o.Status, _ => "Expired"));


Улучшенная поддержка raw SQL с проекцией в DTO, JSON-колонки, батчинг. В итоге для типичных API-ридов с небольшими DTO разница с Dapper составляет около 10–30%, а при доминировании latency на стороне БД она вообще не заметна.

Где Dapper всё ещё выигрывает

Кастомные джоины, CTE, оконные функции, db-specific хинты. Read-mostly микросервисы без change tracking. Хранимые процедуры. Минимальный jitter на p95–p99.

Прагматичный подход

Большинство команд используют гибрид. EF Core по умолчанию для всего с Select + AsNoTracking. Для топ 2–5 горячих запросов пробуют compiled queries. Если мало, реализуют только их через Dapper за интерфейсом (IOrderQueries), а остальное на EF.

Типичные ошибки

Возврат сущностей вместо DTO из API. Lazy loading без контроля. N+1 из-за навигационных свойств. Отсутствие AsNoTracking на ридах. Generic repository, который прячет фичи EF.

Compiled EF vs non-compiled экономит 0.5–2.5 мс на вызов. Если compiled query укладывается в SLO в пределах 15% от Dapper и проще в поддержке, оставляйте EF.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
6
😁 Это точно чистый код?

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#garbage_collector
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔13
📎 Расширение для Visual Studio, которое добавляет все недостающие using

Открываете C# файл, а там десяток красных подчёркиваний. Нажимаете Ctrl+., выбираете нужный namespace, переходите к следующей ошибке, снова Ctrl+.. И так по кругу. Visual Studio умеет добавлять using только по одному. В Rider есть Import Missing References, но это другая IDE.

OhUsings решает эту проблему внутри Visual Studio. Расширение сканирует файл, находит все неразрешённые типы через Roslyn и добавляет нужные using директивы разом. Без ручного перебора.

Как это работает

Под капотом OhUsings использует семантическую модель Roslyn, а не regex. Расширение читает диагностики компилятора (CS0246, CS0103, CS0234 и ещё около десятка), извлекает имена типов и находит подходящие namespace через SymbolFinder. Если тип однозначный, using добавляется автоматически. Если тип встречается в нескольких namespace (например, Timer живёт и в System.Timers, и в System.Threading), расширение покажет диалог выбора.

Добавленные директивы сортируются по алфавиту, System.* ставятся первыми. Всё форматируется через Roslyn.

Три области применения

Можно запустить на текущем файле, на активном проекте или на всём solution целиком.

Установка

Самый простой способ: в Visual Studio 2022 откройте Extensions → Manage Extensions, найдите OhUsings и нажмите Download. После перезапуска расширение готово к работе.

Или соберите из исходников:
git clone https://github.com/MabroukMahdhi/OhUsings.git

Откройте OhUsings.sln в Visual Studio 2022, соберите проект и установите полученный OhUsings.vsix.

Как использовать

Три варианта на выбор. Через меню: Tools → OhUsings: Import All Missing Usings. Через контекстное меню: правый клик в редакторе → OhUsings: Import All Missing Usings. Или через light bulb: ставите курсор на неразрешённый тип, нажимаете Ctrl+. и выбираете действие из предложенных OhUsings.

Результат отображается в статусной строке и Output Window.

Настройки

Расширение поддерживает несколько опций. SortUsings (по умолчанию true) отвечает за сортировку директив. PlaceSystemFirst (по умолчанию true) ставит System.* выше остальных. MaxDiagnosticsPerDocument (по умолчанию 200) ограничивает число обрабатываемых диагностик на файл для защиты производительности.

Ограничения

OhUsings работает только с типами из уже подключённых сборок. Добавлять NuGet пакеты или ссылки на проекты расширение пока не умеет, но это есть в планах. Если тип неоднозначный, его придётся выбрать вручную через диалог.

Итого

OhUsings экономит время на рутине. Вместо того чтобы обходить каждую ошибку по отдельности, вы запускаете одну команду и получаете все нужные using сразу. Расширение бесплатное, с открытым исходным кодом под MIT лицензией, без телеметрии и сетевых запросов.

➡️ Репозиторий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека шарписта

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
11🥱3