Await multiple async Task while setting max running task at a time

后端 未结 4 976
失恋的感觉
失恋的感觉 2020-12-19 12:19

So I just started to try and understand async, Task, lambda and so on, and I am unable to get it to work like I want. With the code below I want for it to lock btnDoWebReque

4条回答
  •  独厮守ぢ
    2020-12-19 12:53

    We can easily achieve this using SemaphoreSlim. Extension method I've created:

        /// 
        /// Concurrently Executes async actions for each item of 
        /// 
        /// Type of IEnumerable
        /// instance of "/>
        /// an async  to execute
        /// Optional, max numbers of the actions to run in parallel,
        /// Must be grater than 0
        /// A Task representing an async operation
        /// If the maxActionsToRunInParallel is less than 1
        public static async Task ForEachAsyncConcurrent(
            this IEnumerable enumerable,
            Func action,
            int? maxActionsToRunInParallel = null)
        {
            if (maxActionsToRunInParallel.HasValue)
            {
                using (var semaphoreSlim = new SemaphoreSlim(
                    maxActionsToRunInParallel.Value, maxActionsToRunInParallel.Value))
                {
                    var tasksWithThrottler = new List();
    
                    foreach (var item in enumerable)
                    {
                        // Increment the number of currently running tasks and wait if they are more than limit.
                        await semaphoreSlim.WaitAsync();
    
                        tasksWithThrottler.Add(Task.Run(async () =>
                        {
                            await action(item);
    
                            // action is completed, so decrement the number of currently running tasks
                            semaphoreSlim.Release();
                        }));
                    }
    
                    // Wait for all tasks to complete.
                    await Task.WhenAll(tasksWithThrottler.ToArray());
                }
            }
            else
            {
                await Task.WhenAll(enumerable.Select(item => action(item)));
            }
        }
    

    Sample Usage:

    await enumerable.ForEachAsyncConcurrent(
        async item =>
        {
            await SomeAsyncMethod(item);
        },
        5);
    

提交回复
热议问题