Обновить
64K+

C# *

Объектно-ориентированный язык программирования

88,17
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Папка как интеграция: файловый обмен в .NET без cron, FileSystemWatcher и самописных костылей

Уровень сложностиСложный
Время на прочтение13 мин
Охват и читатели9.3K

Опрос каталога, ожидание дописи файла, идемпотентность и атомарная запись через temp+rename: файловый обмен как обычный шаг маршрута.

Спросите у любого интегратора, через что реально ходят деньги, и он назовёт файлы. Банк кладёт выписку в каталог на шаре. 1С выгружает заказы в XML по расписанию. Партнёр по EDI шлёт .edi на FTP. Биллинг ночью роняет CDR-файлы на пару гигабайт. Розничная сеть присылает остатки в CSV, потому что так было в 2009-м и никто не собирается это менять. Файловый обмен не «легаси, которое скоро уйдёт», это работающий транспорт, у которого есть ровно одно свойство: он выглядит проще, чем есть.

Проще он выглядит потому, что первая ....

Читать далее

Практическое применение линейной реализации асинхронных операций на примере WPF приложения

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели9.6K

В этой статье я покажу, как использовать IAsyncEnumerable в WPF‑приложении для асинхронных операций. Код полностью рабочий, его можно скопировать и запустить.
Для команд используется библиотека Prism (NuGet: Prism.WPF). Если у вас нет Prism, команды можно реализовать вручную, но в примере используется стандартный подход из Prism.

Предположим нам нужно выполнить поиск устройств по протоколу Modbus RTU или любую другую операцию с результатами.

Часто первым решением становится использовать асинхронную операцию или поток в совокупности с событиями для проброса данных. Но тогда нам необходимо будет управлять подписками на события, пробрасывать данные из внешнего потока в основной UI через Dispatcher.Invoke.

В начале пути я, как и многие, использовал асинхронные операции с событиями, методами‑обработчиками и Dispatcher.Invoke для проброса данных в основной поток. Но если данных много и\или они часто меняются, это создает дополнительные сложности. Так же куча событий, делает код более запутанным и менее масштабируемым.

Начиная с C# 8, появилась возможность использовать IAsyncEnumerable, позволяющие реализовать код профессионального уровня с линейной сигнатурой и преимуществами такими как:

Читать полностью

ZeroTier без native: managed ZtSharp и VL1-only ZtLite для ESP32

Время на прочтение7 мин
Охват и читатели12K

Доброго времени суток.

Интерпретатор ESPB временно пока отложил, интерес к нему оказался скромным. Но подошел к глобальной задаче с другой стороны и на этот раз все крутится вокруг Zerotier. Давно обратил внимание на данную платформу, когда то ковырял libzt - sockets поверх сети Zerotier. Это удобно для приложений, которые находятся вне единой локальной сети и должны общаться сквозь NAT. Думаю, многие хотели бы использовать микроконтроллеры (например, ESP32) для IoT-задач, не заморачиваясь со способами доставки информации на сервер и не завися от того, спрятан ли этот сервер за NAT.

Из этой идеи выросли три связанных проекта:

Читать далее

Бенчмаркая LINQ: подстава с OrderBy — одно условие и полная сортировка

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели9.7K

Одни вызовы после OrderBy проходят набор один раз, другие приводят к полной сортировке. По коду разницы не видно.

Давайте проверим счётчиком обращений к компаратору — на четырёх машинах и четырёх рантаймах.

Читать далее

Как случайно создать облачный кроссплатформенный сервис для Excel

Уровень сложностиПростой
Время на прочтение10 мин
Охват и читатели7.4K

Я работаю в офисе (вспоминается песня "Ленинграда") и моим основным рабочим инструментом уже очень долгое время является Excel. Рискую показаться предвзятым, но на мой взгляд Excel - это лучший продукт Microsoft. И вообще электронные таблицы, как класс приложений, - это абсолютно гениальное изобретение человечества. Наверное многие считают из злом, но давайте пройдемся по фактам:

Читать далее

Бенчмаркая Span.Sort: выбрал компаратор-структуру — и получил 88 байт на вызов

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели9.2K

Перегрузка Span.Sort с компаратором-структурой должна была работать быстрее обычной. Замер показал обратное: памяти она расходует больше всех, а времени тратит больше, чем компаратор-класс — на .NET 8, 9 и 10.

В .NET 11 результат меняется, но не везде.

Читать далее

Как мы прогоняли свой OpenID-сервер через официальный conformance-suite и что он в нас нашёл

Уровень сложностиСложный
Время на прочтение8 мин
Охват и читатели8.2K

Прогон OIDF conformance-suite по redb.Identity: как настроить сьют, почему кликали вручную, и какие реальные баги он нашёл, включая утечку телефона в id_token.

Мы были уверены, что profile-claims в нашем OpenID-сервере отдаются правильно. Юнит-тесты зелёные, демо-прогон зелёный, ручная проверка через curl показывала namefamily_nameemail, всё на месте. Потом мы прогнали сервер через официальный conformance-suite OpenID Foundation, и он показал, что телефон и адрес пользователя лежат в id_token. А id_token уходит третьим сторонам и пишется в логи как доказательство входа. То есть номер телефона пользователя ездил гораздо дальше, чем клиент вообще запрашивал. Это утечка PII, и никакой наш тест её не ловил, потому что мы не знали, что искать.

Про это и статья: как устроен ...

Читать далее

Архитектура движка подбора билетов: три GDS, железная дорога и маршрут, который меняют в дороге

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели9.2K

Референсная архитектура движка подбора билетов на redb: канонная модель, Scatter-Gather по трём GDS и ж/д, дерево-маршрут и saga-переоформление в дороге.

Сотруднику нужно долететь до одного города, доехать поездом до другого и вернуться тем же путём. Одна командировка, билеты из разных систем бронирования. А потом он уже в дороге пишет в телеграм: «планы изменились, летим не туда, перебронируй».

Три системы под самолёты (Amadeus, Sabre, Travelport) исторически несовместимы: разные XML-диалекты одного и того же понятия перелёта, выросшие из мейнфреймов 60–80-х, каждый со своими причудами и полями, которых нет у соседа. Плюс отдельная, никак не связанная с ними система бронирования под железную дорогу: свой формат, своя логика мест и классов, ничего общего по структуре с авиационными GDS. Запросить всё это параллельно, свести разноформатные ответы в одно и собрать валидный маршрут по стыковкам уже само по себе задача не для россыпи if и ручных мапперов.

А дальше человек в дороге меняет ...

Читать далее

Shadow AI — почему инженеры скрывают, что пользуются ИИ

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели7.9K

Слушал подкаст Code of Leadership, выпуск про AI-assisted engineering. Полтора часа про то, как правильно встроить ИИ в разработку: копайлоты, MCP, метрики, место ИИ в SDLC. Разговор хороший, по делу. И где-то в середине проскочил термин, за который я зацепился и с которым хожу уже неделю — shadow AI. Проскочил сноской, в ряду прочих ИБ-рисков, между утечками и комплаенсом.

А я на этой сноске завис. Потому что мне кажется, что она интереснее основного разговора...

Читать далее...

Бенчмаркая try/finally: один finally — и метод в 6,45 раза медленнее

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели6.4K

Один try/finally внутри метода — и он работает в разы медленнее. Сам блок тут ни при чём, он не выполняет ни одной лишней инструкции.

Причина в решении JIT. В .NET 10 его поменяли — но не для всех методов и не при любых настройках.

Читать далее

AS2 в .NET без отдельного Java-гейтвея: EDI-обмен с партнёрами прямо в маршруте

Уровень сложностиСложный
Время на прочтение15 мин
Охват и читатели11K

Если вы поставляете товар в крупную розницу, возите грузы для 3PL-оператора, шлёте платёжные извещения банку или обмениваетесь медицинскими транзакциями X12 — вы почти наверняка обмениваетесь этими документами по AS2. Заказ (EDI 850), счёт (810), уведомление об отгрузке (856), платёжное авизо (820) уходят партнёру не почтой и не через REST, а как подписанный и зашифрованный S/MIME-конверт поверх HTTP, с подписанной квиткой-распиской в ответ. Так работает регламентированный B2B-документооборот в рознице, логистике, финансах, производстве и здравоохранении уже двадцать лет: Walmart, Amazon и их сети поставщиков, банки с host-to-host каналом, автопром, дистрибьюторы — все требуют AS2.

В .NET до сих пор было два пути. Либо коммерческий AS2-шлюз — Cleo, Seeburger, BizTalk — отдельная коробка, отдельная лицензия, отдельная команда сопровождения. Либо Java-сервер с открытым кодом — OpenAS2, Mendelson Community — отдельный JVM-процесс рядом с вашим .NET-бэкендом, со своим inbox-каталогом, откуда документы надо ещё забирать джобой. В обоих случаях AS2 живёт сбоку от вашей интеграции, а не внутри неё.

redb.Route.AS2закрывает этот разрыв: AS2 становится обычным шагом маршрута в вашем .NET-процессе. Приняли конверт от партнёра, расшифровали, проверили подпись, отдали документ в pipeline — провалидировали, трансформировали, положили в Kafka или SQL — и вернули партнёру подписанную расписку. Один процесс, один деплой, одна панель наблюдаемости. Разберём, как это выглядит в коде, где применяется и почему нативный коннектор в ESB выигрывает у отдельного шлюза.

Читать далее

VLAN и одна старая мечта: как я начал делать Visual IDE для сетей

Время на прочтение12 мин
Охват и читатели17K

Кстати, хочу поблагодарить сообщество за обратную связь по EvertyDesk. Я увидел огромное количество замечаний, идей и реальных проверок. Много ребят запускали проект у себя, ковыряли его, находили проблемы, и вместе мы дотащили всё до версии 2.0.1. Да, я перепрыгнул с 0.0.1 почти сразу. Иногда нумерация версий тоже хочет жить быстрее разработчика.

Нейросети очень помогают добивать мелкие и очевидные баги. Это невозможно сравнить с тем, как я работал раньше, и с тем, как работаю сейчас.

Некоторые спрашивали про Contributor в виде cloud. Ребят, было бы стыдно этого не указать. Значительная часть работы действительно идёт в диалоге с нейросетями. Я фанат технологий, и иногда меня в хорошем смысле удивляет, насколько круто они умеют делать рутинную работу.

В целом я считаю, что мы живём в удивительное время.

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

Поэтому я решил начать параллельную серию статей. Помимо своего VST3-плагина для сведения я хочу наконец сделать то, о чём мечтал годами, пока работал ведущим инженером у частного интернет-провайдера.

Читать далее

Ваш кэш в Redis неэффективен, что с этим делать?

Уровень сложностиСредний
Время на прочтение21 мин
Охват и читатели8.7K

Однажды в проде контейнеры одного из сервисов начали падать по OutOfMemory. Контейнерам было выделено по 4 ГБ оперативной памяти, нагрузка была вполне обычной: десятки страниц в секунду.

Расследование показало, что проблема была в JSON-конфиге.

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

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

Казалось бы, если мы запрашиваем один и тот же JSON, размер не должен так критично влиять.

Но всё оказалось интереснее…

Читать далее

Ближайшие события

Локальная база на клиенте: Blazor WebAssembly и MAUI на SQLite — без EF DbContext, Include и миграций

Уровень сложностиСредний
Время на прочтение21 мин
Охват и читатели8.7K

Офлайн-хранилище со сложным графом и outbox: быстрый старт в MAUI и в браузере, базовые операции и почему в этой роли EF Core только мешает.

Курьер спустился в подвал склада — связи нет. Кладовщик третий час принимает поставку в зоне, где вайфай добивает через раз. Пользователь заполнил форму на четыре экрана и нажал «Сохранить» в момент, когда сервер уехал на деплой.

Приложение должно продолжать работать. Значит ему нужна своя база на устройстве: не кеш ответов, а полноценное локальное хранилище, где живут незавершённые документы, локальные состояния и очередь изменений на отправку — тот самый outbox, который дошлёт всё, когда связь вернётся.

И вот тут начинается знакомое.

Читать далее

Пишем Zero‑Allocation конвейер обработки G‑кода на C# (.NET 10): как выжать максимум из железа без GC‑пауз

Уровень сложностиСложный
Время на прочтение19 мин
Охват и читатели9.4K

Если в современных реалиях у разработчика возникает необходимость собрать надежное решение для обработки G‑кода, он обычно смотрит в сторону готовых вариантов (GRBL/FluidNC/Linux‑CNC), либо пишет свой кастомный парсер на С/С++ или Rust и для таких проектов вариант реализации на.NET даже не рассматривается ввиду того, что платформа является управляемой и потому недостаточно надежной (заслуженно или нет — разберем далее).

Читать далее

Как пишут базы данных на C#: RavenDb

Уровень сложностиСредний
Время на прочтение79 мин
Охват и читатели12K

Эта база данных покоряет своей продуманностью: индексы рождаются автоматически, система обновляется без вашего участия, а защита данных стоит на страже, словно крепость. И это лишь начало её возможностей.

Ознакомиться

Бенчмаркая Enumerable.Chunk: почему батчей меньше, а проход до ×2,7 дольше

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели9.5K

Chunk делит коллекцию на массивы — одна строка кода. Но есть размер чанка, после которого он замедляется в разы при тех же данных и той же памяти. А на массиве и на List<int> внутри разный код, и в самой строке этого не видно.

Читать далее

Месяц, 500M токенов и симулятор завода: как мы с ИИ-агентом построили имитационную модель производства чипов

Время на прочтение18 мин
Охват и читатели8K

Когда я прочёл о том, что Андрей Карпати больше не пишет код руками, а перешёл на агентное программирование, я, честно говоря призадумался. Скажи об этом кто-то другой, пропустил бы мимо ушей, но именно его слова стали сигналом - в своей работе, и в группе разработчиков придётся что-то менять. Как известно, личный пример - лучший способ убедить коллектив и повести за собой, поэтому пришлось пробовать.

Первой же пробой пера стал вовсе не Todo-app, а самый что ни на есть хардкорный энтерпрайз. Задача - создать полноценный аналог интеграционной шины CellWorks MBX. Это ключевой элемент автоматизации завода по производству полупроводников: она связывает в единое целое MES-систему и сотню единиц технологического оборудования. Мы как раз начинали перенос легаси-стека с PA-RISC-серверов на x64, и вопрос портирования старого транспорта стоял остро.

Вторым проектом стала имитационная модель этого производства. Нет-нет, это не аналог factorio, в ней ни намёка на 3D или игровые механики. Это симулятор реального цеха: с моделями оборудования, технологическими маршрутами, реальным незавершённым производством, производственным планом на годы вперёд (при желании). Эта модель отвечает на вопрос: какую продукцию и в какой срок я потенциально смогу выпустить, если запущу в работу вот столько-то сырья, и оборудование не встанет надолго из-за поломки или отсутствия материалов. Результат превзошёл ожидания. Софт, который раньше создавался большими коллективами, благодаря ИИ и open-source, теперь можно создавать практически в одиночку, и активно внедрять в реальное производство!

Читать далее

Бенчмаркая StringBuilder: подстава на длинном тексте

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели10K

StringBuilder делит текст на чанки по 8000 символов — вчетверо ниже порога кучи больших объектов. Запас такой, что попасть туда невозможно.

Но чанк на 400 КБ в этой куче возможен и получить его можно разными способами.

Читать далее

Три паттерна написания Agent Skills

Время на прочтение16 мин
Охват и читатели11K

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

Практически каждый современный AI-агент, будь то Claude Code, Cursor, Codex, Gemini CLI или OpenCode, предлагает один и тот же механизм расширения своих возможностей - напишите Skill, опишите процесс решения задачи, добавьте примеры, подключите документацию и агент начнет выполнять эту работу значительно лучше.

Десятилетиями мы учили разработчиков, что Markdown - это документация. Средство общения между людьми. Формат, который не исполняется и никак не влияет на поведение программы, а затем неожиданно оказалось, что один Markdown-файл способен изменить проект сильнее, чем сотни строк кода и здесь индустрия практически мгновенно наступила на старые грабли.

Читать далее