Операция над файлами из очереди в нескольких потоках C#

Есть каталог с файлами, которые надо обработать. Есть массив из 4х потоков. Эти 4 потока должны обработать эти файлы. Файлы у меня добавлены в очередь и должны выбираться из очереди и выполнятся свободным потоком. Как организовать работу с массивом потоков - я не до конца понимаю. Если не сложно, объясните, как можно сделать.

int countfiles; //количество файлов в каталоге
        int countthreads = 4;
        Thread[] threads = new Thread[countthreads];
        Queue<string> filesqueue = new Queue<string>();
        foreach (string file_to_read in filelist)
        {
            filesqueue.Enqueue(file_to_read); //добавить в очередь файлы из каталога
            countfiles++;
        }
        for (int i = 0; i < countthreads; i++)
        {

        }

Ответы (1 шт):

Автор решения: Anatoly
public class MainClass
{
    private List<List<string>> ListOfListsOfFiles;
    private var ListToWorkWithTasks;

    public void MainMethod()
    {
        int countfiles; //количество файлов в каталоге
        int countthreads = 4;
        Thread[] threads = new Thread[countthreads];
        ListOfListsOfFiles = new List<List<string>>(countthreads);

        for (int i = 0; i < filelist.Count; i += countthreads)
        {
            // Прошу простить за этот кривой цикл - не сильно
            // долго над ним думал
            for (int j = i; j < i+4; j++)
            {
                ListOfListsOfFiles[j-i].Add(filelist[j]);
            }
        }

        Task[] arrayOfTasks = new Task[countthreads];
        for (int i = 0; i < countthreads; i++)
        {
            int index = i; // Так надо.
            // Таски стартуют не сразу - могут взять обновлённый i, а
            // последний Task и вовсе выйдет за пределы массива, потому что i
            // уже будет равен 4
            arrayOfTasks[index] = Task.Run(() => 
            {
                VoidForTaskArray(ListOfListsOfFiles[index]); 
            });
        }
        Task.WaitAll(arrayOfTasks);

        // Дальнейшая работа
    }


    private void VoidForTaskArray(List<string> fileAddressList)
    {
        // Общий алгоритм для каждого потока

        // Запись результатов в ListToWorkWithTasks
    }
}

Использовал List а не Queue, так как о Queue узнал только что

→ Ссылка