en
Feedback
Библиотека шарписта | C#, F#, .NET, ASP.NET

Библиотека шарписта | C#, F#, .NET, ASP.NET

Open in Telegram

Все самое полезное для C#-разработчика в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/b60af5a4 Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead

Show more

📈 Analytical overview of Telegram channel Библиотека шарписта | C#, F#, .NET, ASP.NET

Channel Библиотека шарписта | C#, F#, .NET, ASP.NET (@csharpproglib) in the Russian language segment is an active participant. Currently, the community unites 21 865 subscribers, ranking 6 209 in the Technologies & Applications category and 30 824 in the Russia region.

📊 Audience metrics and dynamics

Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 21 865 subscribers.

According to the latest data from 11 June, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by -95 over the last 30 days and by -6 over the last 24 hours, overall reach remains high.

  • Verification status: Not verified
  • Engagement rate (ER): The average audience engagement rate is 12.48%. Within the first 24 hours after publication, content typically collects 7.13% reactions from the total number of subscribers.
  • Post reach: On average, each post receives 2 729 views. Within the first day, a publication typically gains 1 560 views.
  • Reactions and interaction: The audience actively supports content: the average number of reactions per post is 9.
  • Thematic interests: Content is focused on key topics such as .net, шарписта, навигация, await, string.

📝 Description and content policy

The author describes the resource as a platform for expressing subjective opinions:
Все самое полезное для C#-разработчика в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/b60af5a4 Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5c81cdc130259d5b7fead

Thanks to the high frequency of updates (latest data received on 12 June, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.

21 865
Subscribers
-624 hours
-237 days
-9530 days
Posts Archive
👨‍💻 Worker Services и Channels вместо сторонних библиотек Каждый разработчик сталкивался с необходимостью выполнять долгие операции в фоне: отправка писем, обработка платежей, генерация отчётов, синхронизация данных. Обычно первая мысль — взять Hangfire, Quartz или Azure Functions. Но .NET 9 предоставляет встроенные примитивы, которые отлично справляются с этой задачей самостоятельно. Традиционные подходы — блокирующая коллекция и самописные очереди имеют недостатки: требуют ручной синхронизации, рискуют блокировкой потоков, не имеют встроенной поддержки обратного давления. Реализуем очередь задач с помощью каналов и фоновые сервисы Интерфейс и реализация очереди:
public interface IBackgroundTaskQueue
{
    ValueTask QueueAsync(Func<CancellationToken, Task> workItem);
    ValueTask<Func<CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken);
}

public class BackgroundTaskQueue : IBackgroundTaskQueue
{
    private readonly Channel<Func<CancellationToken, Task>> _queue;

    public BackgroundTaskQueue(int capacity = 100)
    {
        var options = new BoundedChannelOptions(capacity)
        {
            SingleReader = false,
            SingleWriter = false,
            FullMode = BoundedChannelFullMode.Wait
        };
        _queue = Channel.CreateBounded<Func<CancellationToken, Task>>(options);
    }

    public async ValueTask QueueAsync(Func<CancellationToken, Task> workItem)
        => await _queue.Writer.WriteAsync(workItem);

    public async ValueTask<Func<CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken)
        => await _queue.Reader.ReadAsync(cancellationToken);
}
Фоновые сервисы для обработки:
public class BackgroundWorker : BackgroundService
{
    private readonly IBackgroundTaskQueue _taskQueue;
    private readonly ILogger<BackgroundWorker> _logger;

    public BackgroundWorker(IBackgroundTaskQueue taskQueue, ILogger<BackgroundWorker> logger)
    {
        _taskQueue = taskQueue;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Фоновый worker запущен");
        
        while (!stoppingToken.IsCancellationRequested)
        {
            var workItem = await _taskQueue.DequeueAsync(stoppingToken);
            try
            {
                await workItem(stoppingToken);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при выполнении задачи");
            }
        }
        
        _logger.LogInformation("Worker останавливается...");
    }
}
Использование в контроллере:
app.MapPost("/send-email", async (IBackgroundTaskQueue queue) =>
{
    await queue.QueueAsync(async token =>
    {
        await Task.Delay(1000, token); // имитация отправки
        Console.WriteLine($"Email отправлен в {DateTime.UtcNow}");
    });
    return Results.Accepted();
});
Запрос возвращается немедленно, а работа продолжается в фоне. Queue автоматически буферизирует задачи, управляет нагрузкой и применяет обратное давление, если очередь переполнится. Когда использовать этот подход Подходит: • Внутренняя обработка задач в приложении • Нет нужды в UI-панели мониторинга • Self-contained сервисы Возьмите библиотеку, если: • Нужна распределённая обработка • Требуется веб-интерфейс для управления • Задачи должны пережить перезагрузку приложения ➡️ Источник 🐸 Библиотека шарписта #sharp_view

❓ Какой пост особенно зашел за эту неделю
Anonymous voting

📰 Шестидневные новости Вспомним, что произошло за 6 рабочих дней. — C# сохраняет популярность Вышел ежегодный Octoverse от G
📰 Шестидневные новости Вспомним, что произошло за 6 рабочих дней. — C# сохраняет популярность Вышел ежегодный Octoverse от GitHub, в котором отмечается рекордный рост числа разработчиков, активность в проектах с AI и смена лидерства по языкам программирования. — Unity Lite. Простой старт в 3D для всех Инструмент от Unity для создания интерактивных 3D-сцен без программирования, с удобной навигацией и редактором внутри браузера/. — Нейросети поиграли в покер Победителем стала модель OpenAI o3 с выигрышем в $36,691 виртуальных денег. Второе место занял Claude Sonnet 4.5, а третье — Grok 4 — Новые кастомные агенты Copilot для .NET GitHub запускает интеллектуальных помощников для оптимизации рабочего процесса .NET‑разработчиков. — Звуки флоппи-дисководов в эмуляторе 🐸 Библиотека шарписта #async_news

☺️ 6 дней труда — пора отдыхать Шестидневная рабочая неделя подошла к концу, и наконец-то время расслабиться. Используйте сво
☺️ 6 дней труда — пора отдыхать Шестидневная рабочая неделя подошла к концу, и наконец-то время расслабиться. Используйте свободное время для восстановления и новых впечатлений. 💬 А вы как планируете провести ближайшие дни? Уже отдыхаете или еще у дел? Ждем ваши ответы в комментариях 👇 🐸 Библиотека шарписта #entry_point

💲 Как договориться о зарплате: 9 стратегий В зарплатных переговорах нет универсального сценария. Но есть проверенные стратег
💲 Как договориться о зарплате: 9 стратегий В зарплатных переговорах нет универсального сценария. Но есть проверенные стратегии под разные ситуации. В статье 9 тактик от открытой до «я никуда не тороплюсь» — с готовыми фразами для собеседования. ➡️ Выбирайте свою в зависимости от опыта, позиции и типа компании 🐸 Библиотека шарписта

✏️ Как найти два повторяющихся числа в массиве Вам дан массив nums длиной n+2, содержащий числа от 0 до n-1. Два числа случайным образом появились в списке дважды. Нужно вернуть эти два числа. Например, для входа [0][1][1][2][3][3][4] ответ будет [1][3]. Для решения можно воспользоваться подсчётом количества появлений каждого числа. Если встретили число во второй раз — записываем его в ответ:
public int[] GetSneakyNumbers(int[] nums)
{
    int n = nums.Length;
    int[] count = new int[101];
    int[] res = new int[2];
    int idx = 0;

    foreach (var num in nums)
    {
        count[num]++;
        if (count[num] == 2)
        {
            res[idx] = num;
            idx++;
        }
    }
    return res;
}
При помощи вспомогательного массива считаем, сколько раз встречается каждое число, и когда оно появилось второй раз — запоминаем. ➡️ Попробовать решить 🐸 Библиотека шарписта #dotnet_challenge

🎃 Хэллоуин и код Сегодня день, когда можно немного отвлечься от кода и рутины. Костюм помогает прочувствовать праздник, даже
🎃 Хэллоуин и код Сегодня день, когда можно немного отвлечься от кода и рутины. Костюм помогает прочувствовать праздник, даже если это всего один день. 💬 Делитесь, кто в костюме сегодня, оставляйте свои истории 👇 🐸 Библиотека шарписта #entry_point

🎃 Хэллоуин в Proglib Academy: скидки, призы и... немного паники Сегодня 31 октября, и это не просто время тыкв и призраков,
🎃 Хэллоуин в Proglib Academy: скидки, призы и... немного паники Сегодня 31 октября, и это не просто время тыкв и призраков, это ПОСЛЕДНИЙ ДЕНЬ, когда ты можешь выиграть макбук! → Купи любой курс со скидкой 40% 💸 → Начни обучение, чтобы пройти 2 недели к 15 ноября 🎓 → Напиши куратору #розыгрыш ✍️ Всё! Теперь ты в игре. 👉 Сейчас или никогда!

👨‍💻 Ленивый фильтр больших файлов Когда файл огромный, главное — не тянуть всё в память. Пример:
var errors = File.ReadLines(logPath).Where(l => l.Contains("ERROR"));
ReadLines читает файл построчно, не загружая всё сразу. Не добавляйте .ToList(), если хочется сохранить ленивость — иначе всё материализуется в памяти. 🐸 Библиотека шарписта #sharp_view

⭐️ Подборка вакансий для шарпистов .NET-разработчик на удалёнку. Backend-developer в Москве от 200 000 ₽. .NET Developer от 200 000 ₽ с удалёнкой. Бустер — Удалённо (в любом городе мира). ➡️ Еще больше топовых вакансий — в нашем канале C# Jobs

⚡️ 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

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

Повышение надёжности .NET-приложений: как обрабатывать сбои и предотвращать каскадные ошибки. Даже самые стабильные системы л
Повышение надёжности .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

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

⚡️ 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

🎁 Конкурс от Proglib Academy! Кстати, если кто-то ещё не в курсе — у нас тут раздают MacBook Pro 14. Да-да, не шутка, настоя
🎁 Конкурс от Proglib Academy! Кстати, если кто-то ещё не в курсе — у нас тут раздают MacBook Pro 14. Да-да, не шутка, настоящий, железный, с M3 Pro Но! Чтобы успеть пройти 2 недели обучения к 15 ноября, курс нужно взять до конца октября — и сейчас на всё скидка 40%. Чтобы поучаствовать, нужно: 1️⃣ Покупаешь любой курс до конца октября; 2️⃣ Проходишь 2 недели обучения к 15 ноября; 3️⃣ Написать куратору в чат #розыгрыш. До 15 ноября, потом всё — поезд (и макбук) уйдёт. 👉 Участвовать в розыгрыше

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