Это потокобезопасная очередь для передачи сообщений между задачами без ручных блокировок и сложной синхронизации.
Что важно знать:
• Работает без ручных блокировок и сложных синхронных вызовов.
• Позволяет автоматически замедлять отправку при перегрузке памяти.
• Обеспечивает плавную передачу данных между параллельными задачами.
Так вы получаете готовый «из коробки» механизм асинхронной очереди с естественным управлением нагрузкой без лишнего кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5❤3👍2
FirstOrDefault() может вернуть null!
В C# часто ищут элемент в коллекции через LINQ:
Если пользователь найден то всё хорошо.
Но если подходящего элемента нет, FirstOrDefault() вернёт значение по умолчанию.
Для ссылочных типов это обычно:
Поэтому такой код может упасть:
Если user оказался null, получим NullReferenceException.
Лучше явно обработать отсутствие результата:
Или выбросить понятную ошибку:
Это особенно важно в API, сервисах, обработчиках команд и бизнес-логике.
➡️ C# Ready | #совет
В C# часто ищут элемент в коллекции через LINQ:
var user = users.FirstOrDefault(u => u.Id == id);
Если пользователь найден то всё хорошо.
Но если подходящего элемента нет, FirstOrDefault() вернёт значение по умолчанию.
Для ссылочных типов это обычно:
null
Поэтому такой код может упасть:
Console.WriteLine(user.Name);
Если user оказался null, получим NullReferenceException.
Лучше явно обработать отсутствие результата:
var user = users.FirstOrDefault(u => u.Id == id);
if (user is null)
{
return;
}
Или выбросить понятную ошибку:
var user = users.FirstOrDefault(u => u.Id == id)
?? throw new InvalidOperationException("User not found");
Это особенно важно в API, сервисах, обработчиках команд и бизнес-логике.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍9🔥4
Почему технические строки не стоит сравнивать через ToLower()?
Для проверки логина, роли или кода часто пишут так:
Код работает во многих случаях, но ToLower() создаёт новую строку и использует правила текущей культуры приложения.
Для обычного текста это может быть полезно. Но логины, роли, ключи конфигурации, HTTP-заголовки и другие технические значения обычно должны сравниваться по стабильным правилам, независимо от языка системы.
Для этого лучше явно указать тип сравнения:
OrdinalIgnoreCase не создаёт промежуточную строку и выполняет регистронезависимое порядковое сравнение. Поведение не изменится после запуска приложения на сервере с другой локалью.
Если же сравнивается текст для пользователя, например названия или элементы поиска, может понадобиться CurrentCultureIgnoreCase.
➡️ C# Ready | #совет
Для проверки логина, роли или кода часто пишут так:
if (role.ToLower() == "admin")
{
GrantAccess();
}
Код работает во многих случаях, но ToLower() создаёт новую строку и использует правила текущей культуры приложения.
Для обычного текста это может быть полезно. Но логины, роли, ключи конфигурации, HTTP-заголовки и другие технические значения обычно должны сравниваться по стабильным правилам, независимо от языка системы.
Для этого лучше явно указать тип сравнения:
if (string.Equals(role, "admin", StringComparison.OrdinalIgnoreCase))
{
GrantAccess();
}
OrdinalIgnoreCase не создаёт промежуточную строку и выполняет регистронезависимое порядковое сравнение. Поведение не изменится после запуска приложения на сервере с другой локалью.
Если же сравнивается текст для пользователя, например названия или элементы поиска, может понадобиться CurrentCultureIgnoreCase.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤6🔥4
Теперь небольшую программу на C# можно запустить прямо из одного файла!
В этой статье:
• Как работают File-Based Apps в .NET 10
• Как запустить .cs-файл без создания отдельного проекта
• Каким способом подключать NuGet-пакеты и дополнительные настройки
• Когда такой формат удобен для скриптов, автоматизации и быстрых экспериментов
Получается знакомая простота скриптовых языков, но с возможностями C# и всей экосистемой .NET.
➡️ C# Ready | #статья
В этой статье:
• Как работают File-Based Apps в .NET 10
• Как запустить .cs-файл без создания отдельного проекта
• Каким способом подключать NuGet-пакеты и дополнительные настройки
• Когда такой формат удобен для скриптов, автоматизации и быстрых экспериментов
Получается знакомая простота скриптовых языков, но с возможностями C# и всей экосистемой .NET.
Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍6❤5
Почему технические строки не стоит сравнивать через ToLower()?
Для проверки логина, роли или кода часто пишут так:
Код работает во многих случаях, но ToLower() создаёт новую строку и использует правила текущей культуры приложения.
Для обычного текста это может быть полезно. Но логины, роли, ключи конфигурации, HTTP-заголовки и другие технические значения обычно должны сравниваться по стабильным правилам, независимо от языка системы.
Для этого лучше явно указать тип сравнения:
OrdinalIgnoreCase не создаёт промежуточную строку и выполняет регистронезависимое порядковое сравнение. Поведение не изменится после запуска приложения на сервере с другой локалью.
Если же сравнивается текст для пользователя, например названия или элементы поиска, может понадобиться CurrentCultureIgnoreCase.
➡️ C# Ready | #совет
Для проверки логина, роли или кода часто пишут так:
if (role.ToLower() == "admin")
{
GrantAccess();
}
Код работает во многих случаях, но ToLower() создаёт новую строку и использует правила текущей культуры приложения.
Для обычного текста это может быть полезно. Но логины, роли, ключи конфигурации, HTTP-заголовки и другие технические значения обычно должны сравниваться по стабильным правилам, независимо от языка системы.
Для этого лучше явно указать тип сравнения:
if (string.Equals(role, "admin", StringComparison.OrdinalIgnoreCase))
{
GrantAccess();
}
OrdinalIgnoreCase не создаёт промежуточную строку и выполняет регистронезависимое порядковое сравнение. Поведение не изменится после запуска приложения на сервере с другой локалью.
Если же сравнивается текст для пользователя, например названия или элементы поиска, может понадобиться CurrentCultureIgnoreCase.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤4🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
Так сказал мой друг из Африки, когда увидел этот стол)
Не знаю уж че за сетап, меня зовут Саша и качественную необычную мебель из натурального дерева я делаю уже больше 12-ти лет, столько же занимаюсь и темой здоровья.
Когда я услышал, что до 10% смертности связано с сидячим образом жизни, меня это поразило и я задался целью делать максимально функциональные и полезные рабочие пространства, ибо геморрой в 30 это конечно довольно нишево, но все же сомнительно 😂
Ну а собрать такой комплект под свои задачи и при этом сразу прикинуть цены вы можете в удобном Mini App конструкторе
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2❤1🔥1
Отправляем несколько HTTP-запросов параллельно на C#!
Если данные нужно получить из нескольких независимых источников, последовательные запросы заставят программу ждать каждый ответ по очереди.
Создадим HttpClient:
Запустим три запроса без немедленного ожидания результата:
Теперь все операции уже выполняются параллельно. Дождёмся завершения всей группы:
Получим готовые результаты:
Если каждый запрос занимает около секунды, последовательное выполнение продлится примерно три секунды, а параллельное около одной.
Добавим ограничение общего времени ожидания:
Передадим токен отмены запросу:
Так приложение сможет прекратить операцию, если внешний сервис отвечает слишком долго.
➡️ C# Ready | #практика
Если данные нужно получить из нескольких независимых источников, последовательные запросы заставят программу ждать каждый ответ по очереди.
Создадим HttpClient:
using var client = new HttpClient
{
Timeout = TimeSpan.FromSeconds(10)
};
Запустим три запроса без немедленного ожидания результата:
Task<string> usersTask =
client.GetStringAsync(usersUrl);
Task<string> ordersTask =
client.GetStringAsync(ordersUrl);
Task<string> ratesTask =
client.GetStringAsync(ratesUrl);
Теперь все операции уже выполняются параллельно. Дождёмся завершения всей группы:
await Task.WhenAll(
usersTask,
ordersTask,
ratesTask
);
Получим готовые результаты:
string users = await usersTask;
string orders = await ordersTask;
string rates = await ratesTask;
Если каждый запрос занимает около секунды, последовательное выполнение продлится примерно три секунды, а параллельное около одной.
Добавим ограничение общего времени ожидания:
using var cts =
new CancellationTokenSource(
TimeSpan.FromSeconds(5)
);
Передадим токен отмены запросу:
string data = await client.GetStringAsync(
usersUrl,
cts.Token
);
Так приложение сможет прекратить операцию, если внешний сервис отвечает слишком долго.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥5❤2
Шпаргалка по форматированию даты и времени в C#!
Например, dd.MM.yyyy выведет дату с числом, месяцем и годом, HH:mm покажет время в 24-часовом формате, а MMM и MMMM позволяют получить сокращённое или полное название месяца.
На картинке спецификаторы для дня, месяца, года, часов, минут, секунд, долей секунды, часового пояса и AM/PM. Для каждого варианта приведены готовый формат и пример результата.
Сохрани, чтобы не потерять!
➡️ C# Ready | #ресурс
Например, dd.MM.yyyy выведет дату с числом, месяцем и годом, HH:mm покажет время в 24-часовом формате, а MMM и MMMM позволяют получить сокращённое или полное название месяца.
На картинке спецификаторы для дня, месяца, года, часов, минут, секунд, долей секунды, часового пояса и AM/PM. Для каждого варианта приведены готовый формат и пример результата.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥7❤3
Почему with у record не создаёт глубокую копию?
Выражение with удобно использовать для создания изменённой копии record:
Но копирование будет поверхностным. Сам record создаётся заново, а вложенные ссылочные объекты продолжают использоваться совместно.
Рассмотрим record со списком:
Создадим его копию и изменим список:
Изменение появится и в исходном объекте:
Причина в том, что original.Roles и copy.Roles ссылаются на один экземпляр List<string>.
Если списки должны быть независимыми, скопируйте коллекцию явно:
Другой вариант использовать неизменяемые коллекции:
Это касается не только списков, но также массивов, словарей и других изменяемых ссылочных объектов.
➡️ C# Ready | #совет
Выражение with удобно использовать для создания изменённой копии record:
var updated = user with
{
Name = "Alex"
};
Но копирование будет поверхностным. Сам record создаётся заново, а вложенные ссылочные объекты продолжают использоваться совместно.
Рассмотрим record со списком:
record User(
string Name,
List<string> Roles
);
Создадим его копию и изменим список:
var original = new User(
"Alex",
new() { "read" }
);
var copy = original with { };
copy.Roles.Add("write");
Изменение появится и в исходном объекте:
Console.WriteLine(
original.Roles.Count
);
// 2
Причина в том, что original.Roles и copy.Roles ссылаются на один экземпляр List<string>.
Если списки должны быть независимыми, скопируйте коллекцию явно:
var copy = original with
{
Roles = new List<string>(
original.Roles
)
};
Другой вариант использовать неизменяемые коллекции:
record User(
ImmutableArray<string> Roles
);
var copy = original with
{
Roles = original.Roles.Add("write")
};
Это касается не только списков, но также массивов, словарей и других изменяемых ссылочных объектов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥5❤3
Интересный разбор того, как сегодня создавать игры на C# без готового движка!
В этой статье:
• Почему C# подходит для небольших кроссплатформенных игр
• Как SDL3 закрывает окна, ввод, контроллеры и рендеринг
• Как организовать загрузку ассетов и собрать собственный редактор на Dear ImGui
➡️ C# Ready | #статья
В этой статье:
• Почему C# подходит для небольших кроссплатформенных игр
• Как SDL3 закрывает окна, ввод, контроллеры и рендеринг
• Как организовать загрузку ассетов и собрать собственный редактор на Dear ImGui
Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤4🔥4
IT мероприятия 🤘
Всё самое интересное для карьеры в IT: митапы, хакатоны, конференции, стажировки и обучение.
Подписывайся🤘
1. Москва
2. Санкт-Петербург
3. Для стажеров и студентов
Всё самое интересное для карьеры в IT: митапы, хакатоны, конференции, стажировки и обучение.
Подписывайся
1. Москва
2. Санкт-Петербург
3. Для стажеров и студентов
Please open Telegram to view this post
VIEW IN TELEGRAM
CancellationToken должен проходить через всю цепочку вызовов!
Само наличие
Если вложенные методы не получили токен, они продолжат работать даже после отмены запроса.
Токен нужно передавать во все операции, которые поддерживают отмену:
Для вычислений без
Отмена в .NET кооперативная:
Для собственного таймаута можно создать источник отмены:
Если одновременно нужен токен вызывающего кода и внутренний таймаут, их можно объединить:
Передавайте
➡️ C# Ready | #совет
Само наличие
CancellationToken в параметрах ещё не делает операцию отменяемой:async Task SyncAsync(CancellationToken token)
{
var data = await LoadAsync();
await SaveAsync(data);
}
Если вложенные методы не получили токен, они продолжат работать даже после отмены запроса.
Токен нужно передавать во все операции, которые поддерживают отмену:
var data = await LoadAsync(token);
await SaveAsync(data, token);
await Task.Delay(500, token);
Для вычислений без
await запрос отмены необходимо проверять вручную:foreach (var item in items)
{
token.ThrowIfCancellationRequested();
Process(item);
}
Отмена в .NET кооперативная:
Cancel() не останавливает код принудительно. Он только сообщает операциям, что работу следует завершить.Для собственного таймаута можно создать источник отмены:
using var timeout = new CancellationTokenSource(
TimeSpan.FromSeconds(10)
);
await SyncAsync(timeout.Token);
Если одновременно нужен токен вызывающего кода и внутренний таймаут, их можно объединить:
using var linked = CancellationTokenSource
.CreateLinkedTokenSource(token, timeout.Token);
await SyncAsync(linked.Token);
Передавайте
CancellationToken до самого нижнего отменяемого вызова, иначе API обещает отмену, но фактическая работа продолжается.Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍4🔥3
«Снова в школу!» – звучит тревожно.
Но в магистратуре МИФИ и Школы 21 «Управление внедрением искусственного интеллекта в бизнес» совсем другая атмосфера: тут нет страха ошибки и ощущения, что зря тратишь время.
Зато есть рабочая среда, поддержка единомышленников и уверенность, что растёшь.
Что внутри программы:
— не просто алгоритмы, а живые сценарии – где применить ИИ, чтобы было лучше, быстрее, дешевле;
— учим внедрять ИИ для управления продуктом от технического задания до запуска;
— делаешь реальные проекты прямо во время учёбы, а не ближе к диплому;
— диплом государственного образца МИФИ – одного из ведущих технических университетов страны.
Подробности и заявка здесь
Но в магистратуре МИФИ и Школы 21 «Управление внедрением искусственного интеллекта в бизнес» совсем другая атмосфера: тут нет страха ошибки и ощущения, что зря тратишь время.
Зато есть рабочая среда, поддержка единомышленников и уверенность, что растёшь.
Что внутри программы:
— не просто алгоритмы, а живые сценарии – где применить ИИ, чтобы было лучше, быстрее, дешевле;
— учим внедрять ИИ для управления продуктом от технического задания до запуска;
— делаешь реальные проекты прямо во время учёбы, а не ближе к диплому;
— диплом государственного образца МИФИ – одного из ведущих технических университетов страны.
Подробности и заявка здесь
👎1🔥1😁1
Это потокобезопасная очередь для передачи сообщений между задачами без ручных блокировок и сложной синхронизации.
Что важно знать:
• Работает без ручных блокировок и сложных синхронных вызовов.
• Позволяет автоматически замедлять отправку при перегрузке памяти.
• Обеспечивает плавную передачу данных между параллельными задачами.
Так вы получаете готовый «из коробки» механизм асинхронной очереди с естественным управлением нагрузкой без лишнего кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9❤5👍3🤝1
Понятный разбор того, как на самом деле работает async/await в C#!
В этой статье:
• Чем асинхронность отличается от запуска работы в отдельном потоке
• Когда await освобождает поток, а когда выполнение продолжается синхронно
• Как компилятор превращает асинхронный метод в машину состояний
➡️ C# Ready | #статья
В этой статье:
• Чем асинхронность отличается от запуска работы в отдельном потоке
• Когда await освобождает поток, а когда выполнение продолжается синхронно
• Как компилятор превращает асинхронный метод в машину состояний
Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤4🔥3