Библиотека шарписта | C#, F#, .NET, ASP.NET
22.6K subscribers
2.43K photos
40 videos
85 files
4.62K links
Все самое полезное для C#-разработчика в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/b60af5a4

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead
Download Telegram
👨‍💻 Три структуры данных, которые игнорируются зря

List<T> — это универсальный солдат C#. Но универсальный не значит оптимальный. Пока вы перебираете 10 000 элементов через .FirstOrDefault(), Dictionary находит нужное за одно обращение. И это только начало.

Queue — когда порядок имеет значение

Обрабатываете задачи по очереди? Вот вам готовое решение:
var tasks = new Queue<UserRequest>();

tasks.Enqueue(new UserRequest { Id = 1, Name = "Alice" });
tasks.Enqueue(new UserRequest { Id = 2, Name = "Bob" });

// Безопасное извлечение (с .NET 6+)
while (tasks.TryDequeue(out var request))
{
await ProcessAsync(request);
}


Первым пришел — первым обработался. Никаких индексов, никаких сортировок.

Stack — для истории действий

Делаете undo/redo или навигацию? Стек решает это из коробки:
var history = new Stack<string>();

history.Push("/home");
history.Push("/products");
history.Push("/cart");

// Вернуться назад
if (history.TryPop(out var lastPage))
{
Console.WriteLine($"Back to: {lastPage}"); // /cart
}


Последнее действие всегда доступно первым. Логика браузерной кнопки «Hазад» готова.

Dictionary — когда нужна скорость

Поиск по ключу за O(1) вместо перебора всего списка:
var users = new Dictionary<int, User>();

users.Add(1, new User { Name = "Alice" });
users.Add(2, new User { Name = "Bob" });

// Безопасная проверка
if (users.TryGetValue(2, out var user))
{
Console.WriteLine(user.Name); // Bob
}


Никаких .FirstOrDefault(x => x.Id == 2) с перебором тысяч записей.

List отлично работает, когда вам нужен доступ по индексу и порядок элементов. Но если задача укладывается в одну из этих трёх структур — используйте их.

🐸 Библиотека шарписта

#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱2210
💾 Всем фичам фича

Вышло октябрьское обновление 86Box — эмулятора ПК IBM PC. Главное новшество — звуки флоппи-дисководов, записанные с реальных устройств.

Разработчик записал звуки с настоящих 3.5" и 5.25" дисководов. Эмулятор отслеживает активность мотора и головки дисковода в реальном времени и проигрывает соответствующие звуки. Получается достоверная звуковая картина — как будто перед вами настоящее железо из 90-х.

➡️ Полный список изменений

🐸 Библиотека шарписта

#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
8🤩1🥱1
👨‍💻 6 дней работы

Внимание! Вы проживаете аномальную неделю прямо сейчас. Вся неделя сдвинулась на один день и мы снова проживаем понедельник.

Или у нас будет две пятницы. Учёные ещё не определились.

💬 Как вы? Уже устали или ещё полны энергии?

🐸 Библиотека шарписта

#entry_point
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥3🥱1
Media is too big
VIEW IN TELEGRAM
Не пропусти МТС True Tech Champ — масштабный фестиваль 21 ноября для тех, кто живет технологиями 🔥

Тебя ждут:

▫️ Захватывающая сюжетная линия. Тебя ждет уникальная кибервселенная с возможностью влиять на ход происходящего.
▫️ Конференция с международными спикерами. Эксперты расскажут о трендах в ИИ и инновациях в индустрии.
▫️ ИТ-качалка. Наращивай экспертизу на воркшопах.
▫️ Шоу-финал ИТ-чемпионата. Более 250 талантов со всей России сразятся в лайв-кодинге и программировании роботов на скоростное прохождение лабиринтов со спецэффектами. Выбирай и болей за фаворитов.
▫️ Айтивности. Тебя ждут бои роботов, кодерские челленджи, пайка плат и не только. Заработай True Coins и обменяй их на стильный мерч.
▫️ HR-Hub. Команда МТС расскажет о возможностях для развития в компании и поможет перезагрузить карьерный трек.
▫️ Афтепати со звездными хэдлайнерами. Зажги под популярные хиты.

Когда: 21 ноября, МТС Live Холл в Москве и онлайн.

Регистрируйся на сайте. Участие бесплатно, количество мест ограничено.
🤩 Как взять последние символы строки в C#

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

Для получения последних 10 символов используется оператор диапазона:
var last10 = text[^10..];


Такой способ делает код короче и легче для чтения.
Но есть один момент — если строка короче десяти символов, программа выбросит ошибку.
Чтобы этого избежать, добавьте проверку:
var last10 = text.Length >= 10 ? text[^10..] : text;


Теперь код работает безопасно даже с короткими строками.

🐸 Библиотека шарписта

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
14🥱3🌚2👾2
🎁 Конкурс от Proglib Academy!

Кстати, если кто-то ещё не в курсе — у нас тут раздают MacBook Pro 14.
Да-да, не шутка, настоящий, железный, с M3 Pro

Но! Чтобы успеть пройти 2 недели обучения к 15 ноября, курс нужно взять до конца октября — и сейчас на всё скидка 40%.

Чтобы поучаствовать, нужно:

1️⃣ Покупаешь любой курс до конца октября;
2️⃣ Проходишь 2 недели обучения к 15 ноября;
3️⃣ Написать куратору в чат #розыгрыш.

До 15 ноября, потом всё — поезд (и макбук) уйдёт.

👉 Участвовать в розыгрыше
3
⚡️ Deadlock в EF Core: как предотвратить

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

В итоге SQL Server прерывает одну из транзакций:
SqlException: Transaction (Process ID xx) was deadlocked on resources...


Пример простого дедлока: два контекста одновременно меняют одну строку и пытаются сохранить изменения. Один запрос блокирует строку, второй вызывает дедлок.
await using var context1 = new AppDbContext();
await using var context2 = new AppDbContext();

var order1 = await context1.Orders.FindAsync(1);
var order2 = await context2.Orders.FindAsync(1);

order1.Status = "Paid";
order2.Status = "Shipped";

await context1.SaveChangesAsync(); // Блокирует строку
await context2.SaveChangesAsync(); // Возможен deadlock


Стратегии предотвращения

• Короткие транзакции

Минимизируйте работу внутри транзакции:
await using var tx = await context.Database.BeginTransactionAsync();
var order = await context.Orders.FindAsync(orderId);
order.Status = "Paid";
await context.SaveChangesAsync();
await tx.CommitAsync();


Избегайте сетевых вызовов и посторонних запросов перед коммитом.

• Правильные индексы

Отсутствие индексов приводит к сканированию таблиц и длительным блокировкам. Используйте SQL Profiler для мониторинга.

• Оптимальный уровень изоляции

ReadCommitted обычно достаточен для большинства операций:
await using var tx = await context.Database.BeginTransactionAsync(
IsolationLevel.ReadCommitted);


• Логика повторов

Используйте встроенную политику retry в EF Core:
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(connectionString, sql =>
sql.EnableRetryOnFailure(
maxRetryCount: 3,
maxRetryDelay: TimeSpan.FromSeconds(5),
errorNumbersToAdd: null)));


• RowVersion для контроля конкурентности

public class Order
{
public int Id { get; set; }
public string Status { get; set; }

[Timestamp]
public byte[] RowVersion { get; set; }
}


EF Core выбросит DbUpdateConcurrencyException при конфликте изменений.

Дедлоки не баги, а следствие паттернов конкурентного доступа.

🐸 Библиотека шарписта

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍6
C#-навигация прямо в браузере? Да, теперь и такое есть! 👀

Для тех, кто работает с C#, приятные новости от SourceCraft. Платформа добавила умную навигацию, которая понимает связи между функциями и позволяет переходить по объявлениям прямо в веб-интерфейсе — как в вашей любимой IDE. 🔥

А ИИ-ассистент теперь дописывает методы на C# не изолированно, а в контексте всего проекта. Для команд с разнесёнными код-ревью или для быстрого онбординга новичков — просто находка. Можно даже коммитить правки из браузера, не теряя типизацию.
🤔7👍3
Повышение надёжности .NET-приложений: как обрабатывать сбои и предотвращать каскадные ошибки.

Даже самые стабильные системы ломаются — вопрос лишь в том, насколько вы готовы к этому. Библиотека Polly позволяет гибко управлять сбоями и повышать устойчивость микросервисов и API.

На открытом вебинаре курса OTUS C# ASP.NET Core разработчик Виктор Дзицкий покажет, как использовать Polly и HttpClientFactory для защиты приложений от временных отказов и непредсказуемых сетевых ошибок.

📌 6 ноября, 20:00
Повышение надежности .NET-приложений с Polly
— ключевые стратегии и политики Polly
— настройка и комбинирование стратегий для сложных сценариев
— защита от каскадных сбоев и готовые паттерны устойчивости
— улучшения в .NET 8

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

👉 Регистрируйтесь: https://clc.to/zyj9ow

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
1
14 вопросов, после которых вам не перезвонят

Разбираем 14 вопросов, которые лучше не задавать на собеседовании: что не так с каждым из них и как переформулировать, чтобы получить нужную информацию без риска для репутации.

➡️ Прочитать статью

🐸 Библиотека шарписта
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱6👍4😁3
⚡️ Deadlock в EF Core: как восстановиться

Даже самая оптимизированная система не застрахована от deadlock на 100%. При высоких нагрузках, пиковых моментах или редких edge-case сценариях они всё равно могут возникнуть. Важно не предотвращение на 100% (это невозможно), а грамотное восстановление.

• Умный ретрай с экспоненциальной задержкой

Простой повтор без задержки только усугубит ситуацию. Используйте экспоненциальную задержку:
public async Task<bool> SaveWithRetryAsync(DbContext context, int maxRetries = 3)
{
for (int attempt = 0; attempt < maxRetries; attempt++)
{
try
{
await context.SaveChangesAsync();
return true;
}
catch (DbUpdateException ex) when (IsDeadlock(ex))
{
if (attempt == maxRetries - 1)
throw;

// Экспоненциальная задержка: 100ms, 200ms, 400ms
var delay = TimeSpan.FromMilliseconds(100 * Math.Pow(2, attempt));
await Task.Delay(delay);

Console.WriteLine($"Deadlock detected, retry {attempt + 1}/{maxRetries}");
}
}

return false;
}

bool IsDeadlock(Exception ex) =>
ex.InnerException is SqlException sqlEx &&
(sqlEx.Number == 1205 || // Deadlock victim
ex.InnerException.Message.Contains("deadlocked"));


• Ограничение параллелизма

Если ваше приложение обрабатывает большие пакеты данных, ограничьте количество одновременных операций:
public class OrderProcessor
{
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(5); // Макс 5 одновременно

public async Task ProcessOrdersAsync(List<int> orderIds)
{
var tasks = orderIds.Select(id => ProcessWithSemaphoreAsync(id));
await Task.WhenAll(tasks);
}

private async Task ProcessWithSemaphoreAsync(int orderId)
{
await _semaphore.WaitAsync();
try
{
await using var context = new AppDbContext();
var order = await context.Orders.FindAsync(orderId);
order.Status = "Processed";
await SaveWithRetryAsync(context);
}
finally
{
_semaphore.Release();
}
}
}


• Логирование и анализ

Недостаточно просто повторить — нужно понять причину:
catch (DbUpdateException ex) when (IsDeadlock(ex))
{
_logger.LogWarning(ex,
"Deadlock on order {OrderId}, attempt {Attempt}/{MaxAttempts}",
orderId, attempt + 1, maxRetries);

// Отправьте метрику в мониторинг
_telemetry.TrackMetric("Deadlocks", 1, new Dictionary<string, string>
{
["Entity"] = "Order",
["Operation"] = "Update"
});
}


• Захват графов блокировок

SQL Server создаёт подробные графы взаимоблокировок. Настройте их захват:
-- Extended Events для захвата deadlock
CREATE EVENT SESSION [DeadlockMonitoring] ON SERVER
ADD EVENT sqlserver.xml_deadlock_report
ADD TARGET package0.event_file(SET filename = N'C:\Logs\Deadlocks.xel')
WITH (MAX_MEMORY = 4096 KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS);

ALTER EVENT SESSION [DeadlockMonitoring] ON SERVER STATE = START;


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

Чтобы строить надёжные решения нужно знать архитектуру и уметь её спроектировать. Для этого можно пройти наш интенсив по архитектуре и шаблонам проектирования. Осталось всего 3 дня скидок!

🐸 Библиотека шарписта

#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍3🔥3