Страницы

Поиск по вопросам

вторник, 23 апреля 2019 г.

Многопоточность для обработки файла

Есть много огромныйх файлов(по 4-6gb), мне нужно запустить примерно 100 потоков, чтобы каждый поток брал следующую строку из файла и обрабатывал.
List _threads; int countThr;
public void Run(int count) { Globals.threadAlive = 0; _threads = new List(); _threads.Clear(); countThr = count; for (int i = 0; i < count; i++) { var thread = new Thread(multiThread); thread.IsBackground = true; _threads.Add(thread); _threads[i].Start(); } }
public void Abort() { Globals.threadAlive = 1; foreach (Thread thr in _threads) { thr.Abort(); } _threads.Clear(); Globals.threadAlive = 0; }
private void multiThread() { for (int c = 0; c < Globals.lines.Length; c++) { //обработка строки } Globals.threadAlive = 1; Abort(); }
Это будет правильное решение моей задачи?


Ответ

Я предлагаю вычитывать с помощью File.ReadLines, это позволяет не загружать весь файл в память.
Разбирать отдельные строки в отдельных задачах для потоков - нерентабельно, скорее всего, зависит от того, как долго занимает обработка одной строки.
Поэтому предложенный вариант разбивает все строки на пакеты небольшого размера (batches) и обрабатывает их параллельно.
void Main() { var filePath = Path.GetTempFileName(); File.WriteAllText(filePath, string.Join(Environment.NewLine, Enumerable.Range(0, 100001)));
var batchSize = 1000;
var allLines = File.ReadLines(filePath);
var processedCount = 0;
GetLinesInBatches(allLines, batchSize).AsParallel().ForAll(batch => { foreach (var line in batch) { Interlocked.Increment(ref processedCount); // Do something with the line. } });
Console.WriteLine("Total: {0}", processedCount); }
IEnumerable> GetLinesInBatches(IEnumerable allLines, int batchSize) { using (var e = allLines.GetEnumerator()) { bool more = false; do { var batch = new List(batchSize); for (var i = 0; i < batchSize && (more = e.MoveNext()); i++) { batch.Add(e.Current); } yield return batch; } while (more); } }

Комментариев нет:

Отправить комментарий