Многопоточность, потокобезопасность. Простая программа по обработке .txt файлов - C#

Узнай цену своей работы

Формулировка задачи:

Добрый день, коллеги. Помогите исправить код. Программа запрашивает количество потоков, делит их между текстовыми файлами исходя из определённой логики. Выводит информацию: номер потока, название файла, который обработался. Во время дебага работает стабильно, во время исполнения без дебага - не так как задумывалось (поток с номером 0 почти никогда не выводится, часто дублируется информация "поток-файл"). Проблема с потокобезопасностью? Как наладить?
using System;
using System.Threading;
using System.IO;
 
class streams
{
    public static void StreamsStart(int threads, string[] directory)
    {
        Thread[] threadArray;
        int filesCount = directory.Length;
        //если количество файлов и потоков равное - каждому потоку по файлу
        if (threads == filesCount)
        {
            for (int i = 0; i < (threadArray = new Thread[threads]).Length; i++)
            {
                threadArray[i] = new Thread(new ThreadStart(() => { ReadFiles(i, directory[filesCount-1]); })) { IsBackground = true };
                threadArray[i].Start();
                filesCount--;
            }
        }
 
        //если количество файлов меньше, чем потоков - потоки делим между файлами, 
        //вначале раздаём всем файлам по 1 потоку
        //потом снова всем (или кому хватит) по 1 потоку и т.д. 
        else if (threads > filesCount)
        {
            for (int i = 0; i < (threadArray = new Thread[threads]).Length; i++)
            {
                if (filesCount < 1)
                {
                    filesCount = directory.Length;
                }
                threadArray[i] = new Thread(new ThreadStart(() => { ReadFiles(i, directory[filesCount-1]); })) { IsBackground = true };
                threadArray[i].Start();
                filesCount--;
 
            }
        }
 
        // если количество файлов больше, чем потоков - файлы делим между потоками, так: Например 26 файлов, 3 потока.
        // 26/3 = 8
        // и 2 в остатке.
        // 2 потока получают 9 файлов, 1 поток 8 файлов.     
        else
        {
            // целое
            int withoutResidue = filesCount / threads; 
            // остаток
            int residue = filesCount % threads; 
            
            for (int i = 0; i < (threadArray = new Thread[threads]).Length; i++)
            {
                threadArray[i] = new Thread(new ThreadStart(() => 
                {
                    //раздаём гарантировано всем потокам по целому набору файлов
                    for (int j = 0; j < withoutResidue; j++)
                    {
                        ReadFiles(i, directory[filesCount-1]);
                        filesCount--;
                    }
                    //если есть остаток, даём каждому потоку по 1 файлу, пока остаток не исчерпается
                    if (residue != 0)
                    {
                        ReadFiles(i, directory[filesCount-1]);
                        filesCount--;
                        residue--;
                    }
                }
                )) { IsBackground = true };           
               threadArray[i].Start(); 
            }
        }
    }
 
    private static readonly object syncRoot = new object();
 
    static void ReadFiles(int thread, string fileName)
    {
        lock (syncRoot)
        {
            using (FileStream file = File.Open(fileName, FileMode.Open))
            using (StreamReader stream = new StreamReader(file))
            {
                while (stream.Peek() >= 0)
                {
                    stream.ReadLine();
                }
                Console.WriteLine("Thread {0}, Filename {1}", thread, file.Name);
            }
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        string[] directory = Directory.GetFiles(@"C:\folder", "*.txt");

        Console.WriteLine("input number of threads");
        int threads = int.Parse(Console.ReadLine());
        streams.StreamsStart(threads, directory);
        // endofprogram
        Console.ReadKey();
    }
}

Решение задачи: «Многопоточность, потокобезопасность. Простая программа по обработке .txt файлов»

textual
Листинг программы
threadArray[i] = new Thread(new ParameterizedThreadStart(k =>
..............
threadArray[i].Start(i);

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4.214 из 5
Похожие ответы