Разбираем 7 инструментов System.Text.Json!
С JSON можно работать как с типизированными объектами, так и без заранее описанной модели. Для потоков есть асинхронные методы, а для выборочного чтения и изменения структуры подходят разные представления документа.
В этой шпоре собраны Serialize, Deserialize, SerializeAsync, DeserializeAsync, JsonDocument, TryGetProperty и JsonNode.
➡️ C# Ready | #шпора
С JSON можно работать как с типизированными объектами, так и без заранее описанной модели. Для потоков есть асинхронные методы, а для выборочного чтения и изменения структуры подходят разные представления документа.
В этой шпоре собраны Serialize, Deserialize, SerializeAsync, DeserializeAsync, JsonDocument, TryGetProperty и JsonNode.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12❤5👍4
Claude снова банит пользователей из РФ
Многим начали приходить письма счастья от Anthropic: аккаунт заблокирован, доступ закрыт. Банят за вход из неподдерживаемого региона и оплату через серые схемы.
А в CatCode Claude работает без ограничений.
CatСode - это десктопный агент с топовыми нейросетями на борту всего за 1550 рублей в месяц:
😒 Claude Fable
🤖 GPT-6 Astra
😐 Grok 4.6
и многие другие.
Твой аккаунт точно не забанят: подписка оформлена у международной компании. Работает без VPN, оплата российской картой или СБП, никаких перекупов. Первые задачи бесплатно, просто зарегистрируйся и пробуй.
Оформи пакет нейросетей разом и не бойся банов: catcode.dev
Многим начали приходить письма счастья от Anthropic: аккаунт заблокирован, доступ закрыт. Банят за вход из неподдерживаемого региона и оплату через серые схемы.
А в CatCode Claude работает без ограничений.
CatСode - это десктопный агент с топовыми нейросетями на борту всего за 1550 рублей в месяц:
и многие другие.
Твой аккаунт точно не забанят: подписка оформлена у международной компании. Работает без VPN, оплата российской картой или СБП, никаких перекупов. Первые задачи бесплатно, просто зарегистрируйся и пробуй.
Оформи пакет нейросетей разом и не бойся банов: catcode.dev
Please open Telegram to view this post
VIEW IN TELEGRAM
👎2😁2❤1
Убираем лишние запросы при вводе текста в C#!
При поиске по мере набора символов приложение может отправить запрос на каждый ввод. Добавим небольшую задержку и отмену предыдущей операции, чтобы искать только по последнему значению.
Храним источник отмены текущего поиска и блокировку для его безопасной замены:
Когда приходит новый текст, заменяем источник под блокировкой и отменяем предыдущий поиск:
Блокировка не даёт старой задаче одновременно освободить источник, который новый вызов пытается отменить. Каждый вызов освобождает свой объект сам после завершения.
Ждём короткую паузу, затем выполняем поиск с тем же токеном отмены:
Если за 300 миллисекунд пользователь введёт следующий символ, ожидание или запрос завершится отменой. Проверка перед показом результата не даст старому поиску перезаписать более свежие данные.
В блоке finally очищаем поле только тогда, когда там всё ещё наш источник, и освобождаем его:
Такой debounce сокращает сетевую нагрузку.
➡️ C# Ready | #практика
При поиске по мере набора символов приложение может отправить запрос на каждый ввод. Добавим небольшую задержку и отмену предыдущей операции, чтобы искать только по последнему значению.
Храним источник отмены текущего поиска и блокировку для его безопасной замены:
private readonly object _searchLock = new();
private CancellationTokenSource? _searchCts;
Когда приходит новый текст, заменяем источник под блокировкой и отменяем предыдущий поиск:
var current = new CancellationTokenSource();
lock (_searchLock)
{
var previous = _searchCts;
_searchCts = current;
previous?.Cancel();
}
Блокировка не даёт старой задаче одновременно освободить источник, который новый вызов пытается отменить. Каждый вызов освобождает свой объект сам после завершения.
Ждём короткую паузу, затем выполняем поиск с тем же токеном отмены:
try
{
await Task.Delay(300, current.Token);
var results = await _searchService.FindAsync(query, current.Token);
current.Token.ThrowIfCancellationRequested();
_view.Show(results);
}
catch (OperationCanceledException) when (current.IsCancellationRequested)
{
}
Если за 300 миллисекунд пользователь введёт следующий символ, ожидание или запрос завершится отменой. Проверка перед показом результата не даст старому поиску перезаписать более свежие данные.
В блоке finally очищаем поле только тогда, когда там всё ещё наш источник, и освобождаем его:
finally
{
lock (_searchLock)
{
if (ReferenceEquals(_searchCts, current))
{
_searchCts = null;
}
}
current.Dispose();
}
Такой debounce сокращает сетевую нагрузку.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍4❤3
🔥 Middle C# на собеседовании у Senior из европейского highload | 20 октября, 19:00 МСК
Можно знать технологию и всё равно завалить техническое интервью. Часто дело не в знаниях, а в том, как ты отвечаешь и какие детали упускаешь ☝🏻
Александр Моргунов, Senior C# разработчик с 7+ годами опыта в европейском highload, проведёт мок-собеседование в прямом эфире!
Отвечает разработчик-доброволец, вопросов он заранее не знает. После каждого ответа Александр разберёт, что было хорошо, где кандидат потерял баллы и как стоило ответить.
Проверяй себя вместе с кандидатом и узнай, к чему подготовиться до своего собеса.
🚀 Это бесплатно
Эфир проходит в рамках менторской программы ШОРТКАТ для C# разработчиков
Ссылка на эфир в боте 👉 @shortcut_csharp_bot
Реклама.
О рекламодателе.
Можно знать технологию и всё равно завалить техническое интервью. Часто дело не в знаниях, а в том, как ты отвечаешь и какие детали упускаешь ☝🏻
Александр Моргунов, Senior C# разработчик с 7+ годами опыта в европейском highload, проведёт мок-собеседование в прямом эфире!
Отвечает разработчик-доброволец, вопросов он заранее не знает. После каждого ответа Александр разберёт, что было хорошо, где кандидат потерял баллы и как стоило ответить.
Проверяй себя вместе с кандидатом и узнай, к чему подготовиться до своего собеса.
🚀 Это бесплатно
Эфир проходит в рамках менторской программы ШОРТКАТ для C# разработчиков
Ссылка на эфир в боте 👉 @shortcut_csharp_bot
Реклама.
О рекламодателе.
Добавляем Request-Id middleware в ASP.NET Core!
Нужно связывать логи, ошибки и ответы API одним идентификатором запроса. Реализуем middleware, который берёт Request-Id из заголовка или создаёт новый.
В этой задаче:
Такой подход помогает быстрее искать конкретный запрос в логах, трассировке, gateway и клиентских жалобах.
➡️ C# Ready | #задача
Нужно связывать логи, ошибки и ответы API одним идентификатором запроса. Реализуем middleware, который берёт Request-Id из заголовка или создаёт новый.
В этой задаче:
• читаем входящий заголовок
• создаём fallback через Guid
• прокидываем значение в response
• подключаем middleware в pipeline
Такой подход помогает быстрее искать конкретный запрос в логах, трассировке, gateway и клиентских жалобах.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤4🔥3
Шпаргалка по регулярным выражениям в .NET!
Regex позволяет находить и заменять текст по шаблону, а готовые методы возвращают результат в удобном для задачи виде. В справочнике собраны короткие примеры вызова и отмечены возможности новых версий .NET.
На картинке есть IsMatch, Match, Matches, Replace, Split, Count, EnumerateMatches, Escape и Unescape. Также показаны RegexOptions и тайм-аут, который ограничивает время поиска при неудачном шаблоне.
➡️ C# Ready | #ресурс
Regex позволяет находить и заменять текст по шаблону, а готовые методы возвращают результат в удобном для задачи виде. В справочнике собраны короткие примеры вызова и отмечены возможности новых версий .NET.
На картинке есть IsMatch, Match, Matches, Replace, Split, Count, EnumerateMatches, Escape и Unescape. Также показаны RegexOptions и тайм-аут, который ограничивает время поиска при неудачном шаблоне.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤3🔥3
Полезный инструмент для IT-айтишников 👇
Если ты разработчик, тестировщик, аналитик или другой специалист из IT и задумываешься о смене работы, присмотрись к этому сервису.
Это проект на базе ИИ, который помогает искать вакансии и упрощает поиск новой работы.
Можно сохранить себе и воспользоваться, когда решишь найти новые карьерные возможности.
Если ты разработчик, тестировщик, аналитик или другой специалист из IT и задумываешься о смене работы, присмотрись к этому сервису.
Это проект на базе ИИ, который помогает искать вакансии и упрощает поиск новой работы.
Можно сохранить себе и воспользоваться, когда решишь найти новые карьерные возможности.
Please open Telegram to view this post
VIEW IN TELEGRAM
Зачем передавать TimeProvider вместо прямого вызова DateTimeOffset.UtcNow?
Если код сам читает системные часы, тест зависит от момента запуска. Передай источник времени явно:
Сервис теперь не привязан к часам машины. В приложении используй системный провайдер:
В тесте установи фиксированное время через FakeTimeProvider:
Создай дату истечения и сдвинь виртуальные часы до границы:
Тест выполняется сразу и точно проверяет границу. Добавь пакет для управляемых часов:
Для управляемых задержек передай тот же провайдер в Task.Delay:
В тесте Advance завершит такое ожидание без реальной паузы. Для измерения скорости используй Stopwatch, а не календарные часы.
➡️ C# Ready | #совет
Если код сам читает системные часы, тест зависит от момента запуска. Передай источник времени явно:
public sealed class ExpirationService(TimeProvider clock)
{
public bool IsExpired(DateTimeOffset expiresAt) =>
clock.GetUtcNow() >= expiresAt;
}
Сервис теперь не привязан к часам машины. В приложении используй системный провайдер:
services.AddSingleton<TimeProvider>(TimeProvider.System);
В тесте установи фиксированное время через FakeTimeProvider:
var clock = new FakeTimeProvider(
new DateTimeOffset(2030, 1, 1, 12, 0, 0, TimeSpan.Zero));
var service = new ExpirationService(clock);
Создай дату истечения и сдвинь виртуальные часы до границы:
var expiresAt = clock.GetUtcNow().AddMinutes(5);
clock.Advance(TimeSpan.FromMinutes(5));
Assert.True(service.IsExpired(expiresAt));
Тест выполняется сразу и точно проверяет границу. Добавь пакет для управляемых часов:
dotnet add package Microsoft.Extensions.TimeProvider.Testing
Для управляемых задержек передай тот же провайдер в Task.Delay:
await Task.Delay(TimeSpan.FromMinutes(5), clock, cancellationToken);
В тесте Advance завершит такое ожидание без реальной паузы. Для измерения скорости используй Stopwatch, а не календарные часы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤5🔥4
Обрабатываем список запросов параллельно с ограничением!
Представь, что нужно отправить тысячи записей во внешний API. Последовательный цикл может работать слишком долго, а запуск тысячи Task сразу создаст всплеск соединений и нагрузки. Соберём обработчик, который ограничивает число одновременных операций и умеет штатно отменяться.
Сначала задаём лимит параллелизма и общий токен отмены:
Число четыре ограничивает одновременно выполняемые обработчики, а не размер всего входного списка. Подбирай значение по лимитам API, пулу соединений и измерениям, а не только по числу ядер процессора.
Передаём каждую запись в асинхронную операцию и не блокируем поток через Wait или Result:
Внутренний token связан с ParallelOptions. Передавай его дальше в HTTP-вызов, чтобы отмена работала не только между элементами, но и во время сетевого ожидания.
Соберём результат ответа и явно обработаем неуспешный HTTP-статус:
Освобождение ответа важно при массовой обработке. Если один запрос вернул ошибку, исключение выйдет из цикла, поэтому вызывающему коду нужно решить, завершать всю пачку, повторять отдельную запись или собирать ошибки поэлементно.
Запусти обработку внутри обычного try и отличай отмену от сбоя сервера:
Ожидаемую отмену обработай отдельно от ошибок сервера:
Сетевые ошибки можно записать отдельно или передать вызывающему уровню:
Parallel.ForEachAsync подходит для независимых элементов, когда важен ограниченный параллелизм. Лимит не задаёт частоту запросов в секунду, не сохраняет порядок завершения и сам по себе не реализует повторы.
➡️ C# Ready | #практика
Представь, что нужно отправить тысячи записей во внешний API. Последовательный цикл может работать слишком долго, а запуск тысячи Task сразу создаст всплеск соединений и нагрузки. Соберём обработчик, который ограничивает число одновременных операций и умеет штатно отменяться.
Сначала задаём лимит параллелизма и общий токен отмены:
var options = new ParallelOptions
{
MaxDegreeOfParallelism = 4,
CancellationToken = cancellationToken
};
Число четыре ограничивает одновременно выполняемые обработчики, а не размер всего входного списка. Подбирай значение по лимитам API, пулу соединений и измерениям, а не только по числу ядер процессора.
Передаём каждую запись в асинхронную операцию и не блокируем поток через Wait или Result:
await Parallel.ForEachAsync(records, options, async (record, token) =>
{
await client.PostAsJsonAsync("/events", record, token);
});
Внутренний token связан с ParallelOptions. Передавай его дальше в HTTP-вызов, чтобы отмена работала не только между элементами, но и во время сетевого ожидания.
Соберём результат ответа и явно обработаем неуспешный HTTP-статус:
await Parallel.ForEachAsync(records, options, async (record, token) =>
{
using var response = await client.PostAsJsonAsync(
"/events", record, token);
response.EnsureSuccessStatusCode();
});
Освобождение ответа важно при массовой обработке. Если один запрос вернул ошибку, исключение выйдет из цикла, поэтому вызывающему коду нужно решить, завершать всю пачку, повторять отдельную запись или собирать ошибки поэлементно.
Запусти обработку внутри обычного try и отличай отмену от сбоя сервера:
try
{
await Parallel.ForEachAsync(records, options, ProcessAsync);
}
Ожидаемую отмену обработай отдельно от ошибок сервера:
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
logger.LogInformation("Обработка отменена");
}
Сетевые ошибки можно записать отдельно или передать вызывающему уровню:
catch (HttpRequestException exception)
{
logger.LogError(exception, "Не удалось отправить запись");
}
Parallel.ForEachAsync подходит для независимых элементов, когда важен ограниченный параллелизм. Лимит не задаёт частоту запросов в секунду, не сохраняет порядок завершения и сам по себе не реализует повторы.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍2🔥2