Шпаргалка по throw и throw ex в C#!
Например, обычный throw внутри catch пробрасывает исходное исключение и сохраняет stack trace. А throw ex создаёт повторный выброс так, что место реальной ошибки становится сложнее найти.
На картинке показана разница между двумя вариантами. Есть сохранение stack trace, потеря исходного контекста, влияние на отладку и короткая таблица с правильным вариантом для catch-блоков.
Сохрани, чтобы не потерять!
➡️ C# Ready | #ресурс
Например, обычный throw внутри catch пробрасывает исходное исключение и сохраняет stack trace. А throw ex создаёт повторный выброс так, что место реальной ошибки становится сложнее найти.
На картинке показана разница между двумя вариантами. Есть сохранение stack trace, потеря исходного контекста, влияние на отладку и короткая таблица с правильным вариантом для catch-блоков.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍4🔥2
Делаем потокобезопасный счётчик через Interlocked!
Иногда нескольким потокам нужно увеличивать одно число. Например, считать обработанные события, успешные запросы или количество ошибок в фоне.
Обычный инкремент выглядит невинно:
Но это не одна атомарная операция. Внутри значение читается, увеличивается и записывается обратно. Если два потока сделают это одновременно, одно обновление может потеряться.
Для таких счётчиков в .NET есть Interlocked:
Теперь увеличение выполняется атомарно. Несколько потоков могут вызывать этот код одновременно, а итоговое значение не потеряет часть инкрементов.
Если нужно прибавить произвольное число, есть Add:
А для чтения текущего значения можно использовать CompareExchange без изменения:
Для long есть отдельные перегрузки, и это часто удобно для метрик, которые могут быстро расти:
Interlocked подходит для простых числовых операций. Если нужно менять сразу несколько полей как одно состояние, лучше использовать lock или отдельную потокобезопасную структуру.
➡️ C# Ready | #практика
Иногда нескольким потокам нужно увеличивать одно число. Например, считать обработанные события, успешные запросы или количество ошибок в фоне.
Обычный инкремент выглядит невинно:
_count++;
Но это не одна атомарная операция. Внутри значение читается, увеличивается и записывается обратно. Если два потока сделают это одновременно, одно обновление может потеряться.
Для таких счётчиков в .NET есть Interlocked:
private int _count;
Interlocked.Increment(ref _count);
Теперь увеличение выполняется атомарно. Несколько потоков могут вызывать этот код одновременно, а итоговое значение не потеряет часть инкрементов.
Если нужно прибавить произвольное число, есть Add:
Interlocked.Add(ref _count, batchSize);
А для чтения текущего значения можно использовать CompareExchange без изменения:
int current = Interlocked.CompareExchange(ref _count, 0, 0);
Для long есть отдельные перегрузки, и это часто удобно для метрик, которые могут быстро расти:
private long _bytes;
Interlocked.Add(ref _bytes, size);
Interlocked подходит для простых числовых операций. Если нужно менять сразу несколько полей как одно состояние, лучше использовать lock или отдельную потокобезопасную структуру.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3🔥2
Напоминалка по async/await в C#!
Например, await приостанавливает выполнение метода до завершения Task, а Task.WhenAll() помогает дождаться нескольких независимых операций.
На картинке основные идеи async/await: зачем нужна асинхронность, что делают async и await, какие бывают return types, как запускать задачи параллельно и каких ошибок стоит избегать.
Сохрани, чтобы не потерять!
➡️ C# Ready | #ресурс
Например, await приостанавливает выполнение метода до завершения Task, а Task.WhenAll() помогает дождаться нескольких независимых операций.
На картинке основные идеи async/await: зачем нужна асинхронность, что делают async и await, какие бывают return types, как запускать задачи параллельно и каких ошибок стоит избегать.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍2🔥2
Парсим простой .env-файл на C#!
В небольших утилитах часто нужно прочитать настройки из файла вида KEY=value: токены, режим запуска, адрес API или путь к директории.
Пример строки:
Разделим её по первому знаку
Сохраним результат в словарь:
Теперь обработаем несколько строк:
Пример
Использование:
Ожидаемый вывод:
Такой парсер не заменяет полноценную библиотеку для сложных
➡️ C# Ready | #практика
В небольших утилитах часто нужно прочитать настройки из файла вида KEY=value: токены, режим запуска, адрес API или путь к директории.
Пример строки:
var line = "APP_ENV=prod";
Разделим её по первому знаку
=:var index = line.IndexOf('=');
var key = line[..index];
var value = line[(index + 1)..];Сохраним результат в словарь:
var config = new Dictionary<string, string>();
config[key] = value;
Теперь обработаем несколько строк:
foreach (var raw in File.ReadLines(".env"))
{
var line = raw.Trim();
if (line.Length == 0 || line.StartsWith("#"))
continue;
var index = line.IndexOf('=');
if (index <= 0)
continue;
config[line[..index]] = line[(index + 1)..];
}Пример
.env:APP_ENV=prod
PORT=8080
DEBUG=false
Использование:
Console.WriteLine(config["APP_ENV"]);
Console.WriteLine(config["PORT"]);
Ожидаемый вывод:
prod
8080
Такой парсер не заменяет полноценную библиотеку для сложных
.env, но отлично подходит для маленьких внутренних утилит.Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍3🔥1
Разбираем immutable collections в C#!
Immutable collections помогают передавать данные без риска, что другой участок кода внезапно изменит коллекцию. Это удобно для конфигов, состояния UI, кешей и событий.
В этой шпоре собраны ImmutableArray, ImmutableList, Add, Remove, SetItem, ToImmutableArray и Builder.
➡️ C# Ready | #шпора
Immutable collections помогают передавать данные без риска, что другой участок кода внезапно изменит коллекцию. Это удобно для конфигов, состояния UI, кешей и событий.
В этой шпоре собраны ImmutableArray, ImmutableList, Add, Remove, SetItem, ToImmutableArray и Builder.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9❤5👍3
Разбираем LINQ: 7 операторов для повседневной выборки данных!
LINQ помогает писать обработку коллекций компактно и выразительно: фильтровать, преобразовывать, сортировать, группировать и искать элементы без ручных циклов. Эти операторы чаще всего встречаются в прикладном C#-коде, API, сервисах и отчётах.
➡️ C# Ready | #шпора
LINQ помогает писать обработку коллекций компактно и выразительно: фильтровать, преобразовывать, сортировать, группировать и искать элементы без ручных циклов. Эти операторы чаще всего встречаются в прикладном C#-коде, API, сервисах и отчётах.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤7🔥5🤝4
Шпаргалка по class, struct и record в C#!
Например, class передаётся по ссылке, struct хранит значение, record class даёт value equality для модели данных, а record struct совмещает value type с удобствами record.
На картинке сравниваются class, struct, record class и record struct. Есть тип хранения, значение по умолчанию, наследование, интерфейсы, immutability, equality, assignment и поведение ToString.
Сохрани, чтобы не потерять!
➡️ C# Ready | #ресурс
Например, class передаётся по ссылке, struct хранит значение, record class даёт value equality для модели данных, а record struct совмещает value type с удобствами record.
На картинке сравниваются class, struct, record class и record struct. Есть тип хранения, значение по умолчанию, наследование, интерфейсы, immutability, equality, assignment и поведение ToString.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍6🔥3
Ограничиваем параллельные запросы через SemaphoreSlim!
Иногда нужно обработать много элементов асинхронно, но не запускать всё сразу. Например, нельзя одновременно ударить сотнями запросов по API или базе.
Наивный вариант запускает все задачи сразу:
Если urls много, приложение может упереться в лимиты сети, rate limit или пул соединений.
Для ограничения параллельности удобно использовать SemaphoreSlim:
Перед началом работы задача ждёт свободное место:
После завершения место обязательно освобождается через finally:
Теперь собираем задачи так, чтобы одновременно работало не больше четырёх:
Такой подход подходит для скачивания файлов, вызовов внешних API, фоновой обработки сообщений и любых задач, где важна скорость, но нельзя терять контроль над нагрузкой.
➡️ C# Ready | #практика
Иногда нужно обработать много элементов асинхронно, но не запускать всё сразу. Например, нельзя одновременно ударить сотнями запросов по API или базе.
Наивный вариант запускает все задачи сразу:
var tasks = urls.Select(DownloadAsync);
await Task.WhenAll(tasks);
Если urls много, приложение может упереться в лимиты сети, rate limit или пул соединений.
Для ограничения параллельности удобно использовать SemaphoreSlim:
var gate = new SemaphoreSlim(4);
Перед началом работы задача ждёт свободное место:
await gate.WaitAsync();
После завершения место обязательно освобождается через finally:
try
{
await DownloadAsync(url);
}
finally
{
gate.Release();
}
Теперь собираем задачи так, чтобы одновременно работало не больше четырёх:
var tasks = urls.Select(ProcessAsync);
await Task.WhenAll(tasks);
Такой подход подходит для скачивания файлов, вызовов внешних API, фоновой обработки сообщений и любых задач, где важна скорость, но нельзя терять контроль над нагрузкой.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5❤3👍3🤝1
Полезная статья про тестирование ASP.NET Core API!
Автор показывает, как уменьшить повторение в интеграционных тестах и собрать удобное окружение с БД, фейковым временем и настройкой под конкретный тест.
В статье автор показывает:
• как устроить тестовое окружение для ASP.NET Core API
• почему setup-код быстро начинает повторяться
• как фикстуры помогают переиспользовать инфраструктуру
➡️ C# Ready | #статья
Автор показывает, как уменьшить повторение в интеграционных тестах и собрать удобное окружение с БД, фейковым временем и настройкой под конкретный тест.
В статье автор показывает:
• как устроить тестовое окружение для ASP.NET Core API
• почему setup-код быстро начинает повторяться
• как фикстуры помогают переиспользовать инфраструктуру
Продолжай читать на Habr
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3🔥3
Коротко и по работному делу!
— Море IT & Digital вакансий на удалёнку
— Каждый день
— Прямые контакты HR
Подписаться на канал 🤘
— Море IT & Digital вакансий на удалёнку
— Каждый день
— Прямые контакты HR
Подписаться на канал 🤘
Собираем простой таймер в C#!
Иногда нужно запустить действие через задержку: показать уведомление, выполнить повторную проверку или отложить сохранение. Но важно уметь отменить задачу, если она уже не нужна.
Создадим CancellationTokenSource:
Теперь напишем отложенное действие:
Запуск выглядит так:
Если пользователь изменил данные ещё раз, старую задачу можно отменить:
Чтобы отмена не выглядела как ошибка, обработаем её отдельно:
Такой подход удобно использовать для debounce-сценариев: например, не сохранять форму после каждого символа, а ждать короткую паузу.
Пример с новым запуском:
В реальном приложении вместо SaveAsync может быть отправка запроса, пересчёт фильтра или обновление превью.
➡️ C# Ready | #практика
Иногда нужно запустить действие через задержку: показать уведомление, выполнить повторную проверку или отложить сохранение. Но важно уметь отменить задачу, если она уже не нужна.
Создадим CancellationTokenSource:
using var cts = new CancellationTokenSource();
Теперь напишем отложенное действие:
static async Task RunLater(
TimeSpan delay,
Func<Task> action,
CancellationToken token)
{
await Task.Delay(delay, token);
await action();
}
Запуск выглядит так:
var task = RunLater(
TimeSpan.FromSeconds(3),
() => SaveAsync(),
cts.Token
);
Если пользователь изменил данные ещё раз, старую задачу можно отменить:
cts.Cancel();
Чтобы отмена не выглядела как ошибка, обработаем её отдельно:
try
{
await task;
}
catch (OperationCanceledException)
{
Console.WriteLine("Задача отменена");
}
Такой подход удобно использовать для debounce-сценариев: например, не сохранять форму после каждого символа, а ждать короткую паузу.
Пример с новым запуском:
cts.Cancel();
using var nextCts = new CancellationTokenSource();
await RunLater(
TimeSpan.FromSeconds(1),
() => SaveAsync(),
nextCts.Token
);
В реальном приложении вместо SaveAsync может быть отправка запроса, пересчёт фильтра или обновление превью.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤3🔥2
Разбираем CancellationToken 7 приёмов для отмены операций!
CancellationToken помогает останавливать долгие операции без грубого убийства потока и без ручных глобальных флагов.
В этой шпоре: CancellationToken, CancellationTokenSource, CancelAfter, ThrowIfCancellationRequested, IsCancellationRequested, CreateLinkedTokenSource и Register.
➡️ C# Ready | #шпора
CancellationToken помогает останавливать долгие операции без грубого убийства потока и без ручных глобальных флагов.
В этой шпоре: CancellationToken, CancellationTokenSource, CancelAfter, ThrowIfCancellationRequested, IsCancellationRequested, CreateLinkedTokenSource и Register.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍3❤2🤝1