30-дневное испытание .NET. День 14. Ограничьте количество одновременных асинхронных операций

30-дневное испытание .NET. День 14. Ограничьте количество одновременных асинхронных операций

3 апреля 2024 г.

Введение

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

Цели обучения

  • Распространенная ошибка всех разработчиков.
  • Как ограничить количество одновременных асинхронных операций
  • Рекомендации

Необходимые требования для разработчиков

  • Базовое понимание языка программирования C#.
  • Базовое понимание асинхронного программирования с использованием async await.

Начало работы

Распространенная ошибка всех разработчиков

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

    (async item => await ProcessItem(item));
    /// <summary>
    /// Old approach with classic async await 
    /// </summary>
    /// <returns></returns>
    public async static Task OldApproach(List<string> items)
    {
        var tasks = items.Select(async item => await ProcessItem(item));
        await Task.WhenAll(tasks);
    }

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

Оптимизированный подход с ограничением параллелизма

Давайте преобразуем приведенный выше метод с помощью SemaphoreSlim, чтобы ограничить количество одновременных асинхронных операций. Следующий фрагмент кода демонстрирует более усовершенствованный подход.

    /// <summary>
    /// Optimized approach with limit concurrency
    /// </summary>
    /// <returns></returns>
    public static async Task OptimizedApproachAsync(List<string> items, int maxConcurrency = 10)
    {
        using (var semaphore = new SemaphoreSlim(maxConcurrency))
        {
            var tasks = items.Select(async item =>
            {
                await semaphore.WaitAsync(); // Limit concurrency by waiting for the semaphore.
                try
                {
                    await ProcessItem(item);
                }
                finally
                {
                    semaphore.Release(); // Release the semaphore to allow other operations.
                }
            });

            await Task.WhenAll(tasks);
        }
    }

Вышеупомянутый код предотвращает перегрузку системы слишком большим количеством одновременных задач.

Рекомендации

Ниже вы найдете лучшие практики

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

Чтобы сбалансировать нагрузку и ресурсы системы, рекомендуется использовать SemaphoreSlim

Как избежать блокировки вызовов

Избегайте использования .Result или .Wait(), поскольку они могут привести к взаимоблокировкам и снижению производительности.

Полная асинхронность

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

Заключение

Асинхронное программирование на C# предполагает нечто большее, чем просто понимание ключевых слов async и await; для этого требуется больше функций, таких как параллелизм, использование ресурсов и структура кода.

Полный код на GitHub

GitHub — ssukhpinder/30DayChallenge.Net

Программирование на C#🚀

Спасибо, что являетесь частью сообщества C#! Прежде чем уйти:

Если вы дошли до этого момента, выразите свою признательность аплодисментами и подпишитесь на автора! 👏️️

Следуйте за нами: X | LinkedIn | Dev.to | Hashnode | Информационный бюллетень | Tumblr

Посетите другие наши платформы: GitHub | Instagram | Тикток | Квора | Daily.dev

Больше материалов на странице Программирование на C#


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE