Обновить
256K+

C# *

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

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

Как я перестал лазить в настройки Windows ради прокси и написал переключатель на 150 строк

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

Часть рабочих сервисов доступна только через прокси. Чтобы открыть один ресурс — прокси надо включить, для остального — выключить. И так по кругу. В Windows 11 путь до этого тумблера — шесть кликов и три вложенных окна: «Параметры» → «Сеть и Интернет» → «Прокси-сервер» → «Настройка вручную» → «Настройка» → переключить → «Сохранить». Каждый раз, когда нужно щёлкнуть один флажок. В итоге я написал ProxyToggle — крохотную утилиту, которая живёт в системном трее. Один клик по иконке включает прокси, ещё клик выключает. Зелёная иконка — прокси активен, серая — нет. В статье разбираю, как она устроена: какие два значения в реестре Windows отвечают за прокси, как через WinINet API заставить изменения примениться мгновенно без перезагрузки, почему иконка рисуется прямо в коде, а адрес сервера вынесен в отдельный файл. И главное — почему утилита весит меньше десяти килобайт и собирается компилятором C#, который уже лежит в каждой Windows, без Visual Studio и без интернета.

Читать далее

Новости

О, сколько нам открытий чудных готовит COM STA-дедлок

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

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

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

Речь пойдет об очень необычной причине дедлока GUI-потока в оконных приложениях .NET – WinForms и WPF. Когда такое приложение виснет намертво, разработчик ищет причину там, где привык: в собственных локах, в гонке между своими потоками, в неудачном lock или забытом .Wait(). Он перетряхивает свой код - и нередко не находит ничего криминального. Потому что причина лежит не этажом ниже, чем он смотрит, и даже не в подвале: в механизме, который он не писал, не видит и с которым, как ему кажется, вообще не работает.

Если вы работаете с WinForms/WPF, то вы наверняка знаете, что весь GUI-стек построен на однопоточной модели COM -  Single-threaded apartments: буфер обмена, drag-drop, общие диалоги, shell-интеграция, OLE - всё это STA-компоненты.

У WinForms сгенерированная точка входа Main имеет явный атрибут [STAThread] (видно прямо в шаблоне), у WPF точка входа генерируется автоматически и тоже имеет атрибут [STAThread].

Читать далее

RMS: упрощаем сотрудникам жизнь в поиске Internet-ID

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

Привет! Я — Саша Басун, инженер направления пользовательских ИТ-сервисов в «Петрович-Тех». Сегодня я пришёл к вам с историей о том, как вывод значения ключа из реестра Windows может упростить обработку заявок в отделе технической поддержки.

Если коротко: помощь со стороны нашей техподдержки нередко начиналась с мема «Давайте поможем Даше найти Internet-ID на рабочем столе». Тут нет-нет, да все стадии от гнева до принятия пройти придётся. В итоге после заявки, которая пришла уже мне, родилось маленькое, но изящное решение на C#. 

Читать далее

Нейрогенератор игровых миров. Часть 2: «оно» ожило

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

Два года назад я пытался сделать генератор RPG-игр на GPT-4 и Stable Diffusion: пользователь пишет промпт, а на выходе получает не чат с бесконечной импровизацией, а готовую консистентную игру с миром, персонажами и геймплеем. Тогда технологии едва справлялись даже с ASCII-картами и простыми ассетами.

Сейчас мы вернулись к идее уже с финансированием, новым пайплайном и моделями, которые позволяют генерировать локации, NPC, тайлы, сюжетные ветки, озвучку, музыку и боёвку. В этой части расскажу, как мы прошли путь от неудачного open-world прототипа к пошаговой 2.5D narrative RPG, сколько это стоит и почему «сгенерировать игру» оказалось сложнее, чем просто попросить нейросеть придумать мир.

Читать далее

Как я написал BGP-сервер и не сошёл с ума

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

BGPLite — open-source BGP route-server на C# и .NET 10. Он принимает BGP-сессии, динамически загружает префиксы через RIPE Stat и управляется через HTTP API. В статье разберём архитектуру проекта и реализацию собственного BGP-сервера с нуля.

Читать далее

Интеграция ИИ уровня предприятия: встраивание LLM в бизнес-процессы крупных компаний — redb.Route.Llm 3.1.1

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

redb экосистема

В предыдущей статье я анонсировал redb.Route.Llm как 24-й транспорт redb.Route — мы делали LLM ещё одним endpoint'ом наравне с Kafka, RabbitMQ и HTTP, чтобы выкинуть отдельную «AI-инфраструктуру», стоящую рядом с интеграционной. Заодно я повесил в конец статьи «честный skip-list» — список того, что в 3.1.0 ещё не доделано: streaming, ToolCacheStore, KnowledgeStore, BatchStore, EvalRunStore, sliding-window память, sandbox-инструменты.

Из этого skip-list'а делано больше, чем я планировал. Но не это главное. Главное — что в процессе доделывания обнаружилась настоящая ценность всей затеи: LLM-транспорт оказался не очередным чат-фреймворком, а недостающим звеном в ESB, после которого «бизнес-агент в проде» перестаёт быть отдельным проектом. Эта статья — про то, как чат-демо превращается в enterprise-агентскую платформу, не переписываясь и не превращаясь в «AI-монолит сбоку».

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

Читать далее

Инкрементальный парсер на c#

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

Создаю собственный DSL на C#: рассказываю о том, как инкрементальный парсер. И наконец-то будет использовать одно из преимуществ рослиновской модели синтаксиса.

Читать далее

Быстрый поиск причин сбоев в логах с помощью EventId в .NET Core на примере актов для единого реестра интернет-рекламы

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

Привет, Хабр! На связи Андрей Алексеенко, техлид оператора рекламных данных (ОРД) «МедиаСкаут». В предыдущем посте мы начали рассказывать о том, как своевременно передаем информацию в единый реестр интернет-рекламы (ЕРИР) — показали настройку гарантированной доставки данных внешним сервисам. Сегодня предлагаю пойти дальше и обсудить, что мы сделали, чтобы вовремя находить, локализовать и устранять проблему, если по какой-то причине (а их множество, и потому разбирать нет смысла) доставка все же не случилась.

Речь о наблюдаемости за системой, которая держится на трех принципах: логирование, трассировка, метрики. В материале разберем механизм контекста структурированного логирования и посмотрим на примерах, как использовать EventId в .NET Core для классификации событий в логах, чтобы быстро понимать, где и что сломалось. Итак, поехали!

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

Механизм создания многосегментных компонентов WPF на примере 7 и 16 сегментов

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

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

Читать далее

Kafka в проде: как встроенное сжатие спасло кластер, когда retention не успевал чистить диск

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

Привет, Хабр! Меня зовут Павел, я ведущий разработчик. В этой статье расскажу про Kafka, consumer groups, lag, offset commit и встроенное сжатие сообщений. Не в формате “что такое Kafka за 15 минут”, а через обычную продовую историю, где кластер начал есть диск быстрее, чем политики очистки успевали его освобождать.

Снаружи проблема выглядела банально: Kafka живет, producer’ы пишут, consumer’ы читают, retention настроен. Внутри было веселее: в пиковую нагрузку место на брокерах улетало так бодро, будто у него был отдельный KPI на исчезновение. Retention вроде бы должен был чистить старые данные, но он не маг. Если входящий поток крупных сообщений быстрее, чем Kafka успевает освобождать сегменты, диск все равно закончится. А когда диск заканчивается у Kafka, настроение портится не только у Kafka.

В итоге мы пришли к встроенному сжатию Kafka на producer’ах. Без ручного zip payload, без “давайте завернем JSON в архив и пусть каждый consumer теперь разбирается сам”. Просто включили compression на уровне Kafka-клиента. В нашем случае объем сообщений на хранении уменьшился примерно в 5 раз. Это не отменило необходимость следить за retention, lag и consumer groups, но дало кластеру перестать жить в режиме “еще один пик, и пишем посмертную”.

Читать далее

Renga API: Создание объектов

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

Одна из главных автоматизаций в BIM – создание объектов. Разбираем создание объектов через Renga API шаг за шагом.

Читать далее

redb.Route 3.1.0 — LLM как ещё один транспорт: .To(«llm://claude») и .AsLlmTool()

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

Серия: redb ecosystem (анонс, разбор позже)

В 3.1.0 у redb.Route вышло два новых транспортаredb.Route.Llm (24-й) и redb.Route.Exec (25-й). LLM теперь — обычный endpoint наравне с Kafka, RabbitMQ и HTTP: вызов модели — это шаг .To("llm://claude"), инструмент агента — это маршрут с .AsLlmTool("shell"), периодический агент — From("llm://factory?schedule=5m"). Exec — спавнер процессов с allowlist, working-dir и таймаутом; работает и как backend shell-инструментов агента, и как самостоятельный scheduled consumer (cron-less health-probes, бэкапы и т.п.). Никаких «отдельных AI-фреймворков рядом с ESB»: всё внутри той же DSL, тех же retry/throttle/circuit-breaker/audit, тех же OpenTelemetry-трейсов.

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

Если читаете про redb.Route впервые — короткий контекст из предыдущих статей серии:

redb.Route — Apache Camel для .NET — зачем вообще, и почему «Apache Camel под .NET»

redb.Route изнутри: четыре in-memory канала и Exchange — как устроен runtime

redb.Route 3.0.1 — плоская навигация по DSL, рефакторинг CRTP и тихий null — предыдущий патч перед 3.1.0

Самое короткое объяснение

From("kafka://orders") .To(Llm.Factory("claude").Temperature(0.2).MaxTokens(1024).AsUri()) .To("kafka://orders.translated");

Читать далее

Anti-corruption Layer на C#: три шва на проекте миграции с Rails

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

Anti-corruption layer в учебниках выглядит как одна аккуратная коробка между чужой системой и вашей: всё чужое остаётся снаружи, внутрь проходит только то, что уже переведено на язык вашего домена. Граница ровная, как по линейке. Почти за год, что мы вытесняли 10-летний Rails-монолит на .NET, такой ровной границы я не увидел ни разу – ни у себя, ни, кажется, у кого-то ещё на живом проекте.

Понятно это стало в первую же неделю. Мы открыли таблицу exercises и нашли в одной JSONB-колонке 14 разных форм одного типа задания, слепленных за 10 лет. Смаппить это в новые DTO как есть – и новая модель отрастит ровно ту же форму, что у Rails. “Нужен ACL”, подумали мы. Только, как выяснилось на практике, не один.

Читать далее

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

REDB: индексы, или почему на любую схему — это быстро

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

В предыдущей части цикла разобрали 13 таблиц REDB: как устроены objectsvaluesstructures, как RTTI-хранение значений отличается от старого EAV-паттерна, зачем нужен scheme_metadata_cache. Если не читали — начните с неё, без понимания схемы дальше тяжело.

В этой статье — то, что обычно идёт следующим вопросом: «А индексы где? У вас же значения всех полей лежат в одной таблице. Любой WHERE — это Seq Scan по миллионам строк».

Это статья 1.1, а не 2 — потому что она прямое продолжение разговора про физическое хранение. Глубокое погружение в C# — это статьи 3-5 цикла: Code-first схемы (SyncSchemeAsync<T>), CRUD (SaveAsync/LoadAsync), LINQ-транслятор. Здесь разговор остаётся в плоскости БД и DDL.

Цифры, на которые опираемся, — с реального прода: TSUM, логистическая система, обслуживает движение грузовиков и заказов через РЦ.

Читать далее

Пишем Third Person Controller на MonoGame. Часть II

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

Это вторая часть серии туториалов, где мы реализуем Third Person Controller на MonoGame. В этой части мы заменим капсулу персонажа на анимированную модель. И прицепим меч на спину.

Читать далее

Как упростить тестирование ASP.NET Core API

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

Разрабатывая приложения, мы стараемся не злоупотреблять дублированием кода. Из часто встречающегося кода мы формируем библиотеки, а для их соединения в инфраструктуре ASP.NET Core приложения используем DI-контейнер. Инфраструктура тестирования для ASP.NET Core API, как правило, тоже повторяется, но какие инструменты помогают нам переиспользовать тестовый код?
Разработчики Python решают эту задачу с помощью pytest.fixtures, однако в dotnet-экосистеме (xUnit) хорошего аналога пока нет.
В статье рассмотрим пример, как в несколько строк собрать полноценное интеграционное окружение с изолированной БД, фейковым временем и случайностью, а также как донастроить это окружение для отдельно взятого теста.

Для кого эта статья: для бэкенд-разработчиков (на .NET), технических лидов, QA-инженеров, которые пишут код, и всех, кто устал от бессмысленно повторяющегося кода в тестах.

Если вы пишете на C#, но хотите добавить тестам элегантности Python — добро пожаловать.

Читать далее

NetFix: как я сделал GUI-обёртку для Zapret и TgWsProxy, которой самому приятно пользоваться

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

Написал это для друга чтобы он не звонил мне с вопросом «почему Telegram не работает».
А теперь звонит с вопросом «когда обновление»... Прогресс)

NetFix - это GUI-приложение для Zapret и TgWsProxy с ПОЛНОЙ автоматизацией. Не просто запуск, оно само скачивает, само настраивает, само следит, само обновляет. Одна кнопка вместо батников, конфигов и консоли.

Что внутри, как это работает и почему там есть даже ритм-игра - читайте далее 👇

Читать далее

Почему OSDev никогда не превратят в конструктор

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

Всем доброго времени суток. В этой статье разжуем некоторые проблемы OSDev'а в том виде, в котором его хотят видеть люди.

Обсудим «конструкторы ОС» и все его плюсы и недостатки.

Читать далее

p99 ×4 после деплоя на ровном месте: как Dynamic PGO в .NET 9 роняет ваш сервис по первым 30 вызовам

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

В .NET 9 Dynamic PGO включён по умолчанию, и это не просто “ещё +10–15% перформанса в релиз-ноутах”. Это новая среда обитания вашего кода. Один и тот же бинарник на одной и той же машине может работать в 3–5 раз медленнее или быстрее в зависимости от того, какие данные он увидел в первые секунды жизни.

Я называю это эффектом JIT-дрифта: метод “застывает” под профиль ранней нагрузки и потом не успевает перестроиться под реальный продакшен. Ниже - минимальный воспроизводимый пример на 20 строк, разбор того, что именно RyuJIT решает за вас, и чек-лист, как с этим жить на проде.

Читать далее

Ошибки и подозрительные места в исходниках .NET 10

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

Чуть больше полугода назад состоялся релиз .NET 10. Остались ли дефекты в исходном коде проекта, спустя месяцы после релиза? Постараемся сегодня найти ответ на этот вопрос.

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