Processing only n items at a time concurrently using Task Parallel Library

前端 未结 3 660
醉话见心
醉话见心 2021-02-08 23:09

This is all happening in a windows service.

I have a Queue (actually a ConcurrentQueue) holding items waiting to be processed

3条回答
  •  日久生厌
    2021-02-08 23:39

    Here is one idea that involves creating an extension method for TaskFactory.

    public static class TaskFactoryExtension
    {
        public static Task StartNew(this TaskFactory target, Action action, int parallelism)
        {
            var tasks = new Task[parallelism];
            for (int i = 0; i < parallelism; i++)
            {
                tasks[i] = target.StartNew(action);
            }
            return target.StartNew(() => Task.WaitAll(tasks));
        }
    }
    

    Then your calling code would look like the following.

    ConcurrentQueue queue = GetQueue();
    int n = GetDegreeOfParallelism();
    var task = Task.Factory.StartNew(
      () =>
      {
        T item;
        while (queue.TryDequeue(out item))
        {
          ProcessItem(item);
        }
      }, n);
    task.Wait(); // Optionally wait for everything to finish.
    

    Here is another idea using Parallel.ForEach. The problem with this approach is that your degrees of parallelism might not necessarily be honored. You are only indicating the maximum amount allowed and not the absolute amount.

    ConcurrentQueue queue = GetQueue();
    int n = GetDegreeOfParallelism();
    Parallel.ForEach(queue, new ParallelOptions { MaxDegreeOfParallelism = n },
      (item) =>
      {
        ProcessItem(item);    
      });
    

提交回复
热议问题