Using a the ConcurrentQueue class and ConcurrentDictionary class with TPL (simple example).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using System.Threading;

namespace Rextester
{
    public class Person
    {
        public int Id {get;set;}
        public string Name {get;set;}
    }

    public class Program
    {
        public static ConcurrentQueue<Person> concurrentQueue = new ConcurrentQueue<Person>();

        public static void Main(string[] args)
        {
            var items = 50;
            for (int i = 0; i < items ; i++)
            {
                var person = new Person();
                person.Id = i;
                person.Name = string.Format("My name is {0}", i);

                concurrentQueue.Enqueue(person);
            }

            var people = new ConcurrentDictionary<int,string>(items, items);

            Task[] queueTasks = new Task[20];
            for (int i = 0; i < queueTasks.Length; i++)
            {
                queueTasks[i] = Task.Factory.StartNew(() =>
                {
                    while (concurrentQueue.Count > 0)
                    {
                        Person currentElement;
                        bool success = concurrentQueue.TryDequeue(out currentElement);
                        if (success)
                        {
                            people.TryAdd(currentElement.Id, currentElement.Name);
                        }
                    }
                });
            }

            Task.WaitAll(queueTasks);

            string name = string.Empty;

            for (int i = 0; i < items ; i++)
            {
                people.TryGetValue(i, out name);
                Console.WriteLine(name);
            }

        }
    }
}