/// <summary> /// Запись происходит в один поток, так как требуется упорядочить сжатые блоки по Id через Hashtable /// </summary> private void WritingThread(object obj) { FileDescriptor writeFileDescriptor = obj as FileDescriptor; try { using (FileStream writeFileStream = writeFileDescriptor.GetDescription.OpenWrite()) { while (_lastWritedBlock < _totalCount && !_cancellationToken.IsCancellationRequested) { ITaskInfo taskInfo = _writeTaskPool.NextTask() as ITaskInfo; if (taskInfo == null) { Thread.Sleep(1); continue; } taskInfo.Execute(writeFileStream); _lastWritedBlock++; } } } catch (Exception exc) { Console.WriteLine("Error on file writing"); #if DEBUG Console.WriteLine(exc); #endif } }
/// <summary> /// Метод для потока чтения. Чтение и генерация задач сжатия происходит в 1 поток, что даёт максимальную нагрузку на диск /// </summary> /// <param name="obj"> /// Дескриптор файла для записи /// </param> private void ReadingThread(object obj) { FileDescriptor read_file = obj as FileDescriptor; try { using (FileStream _fileToBeCompressed = read_file.GetDescription.OpenRead()) { Int64 lastBlock = 0; while (lastBlock < _totalCount && !_cancellationToken.IsCancellationRequested) { // Защита от переполнения памяти if (_compressTaskPool.TaskCount() > _maxTasks * _cores) { Thread.Sleep(1); continue; } ITaskInfo taskInfo = null; taskInfo = _readTaskPool.NextTask(); if (taskInfo == null) { Thread.Sleep(_sleep); continue; } _compressTaskPool.AddTask(_taskFactory.CreateProcessTaskInfo(lastBlock++, (taskInfo.Execute(_fileToBeCompressed) as byte[]))); } #if DEBUG Console.WriteLine("End of reading"); #endif } } catch (Exception exc) { Console.WriteLine("Error on file reading"); #if DEBUG Console.WriteLine(exc); #endif } }
/// <summary> /// Сжатие и генерация задач записи работает в том количестве потоков, сколько процессоров доступно системе, /// давая распределённую и почти 100% нагрузку на все ядра процессора /// </summary> private void CompressingThread() { try { while (_lastZippedBlock < _totalCount && !_cancellationToken.IsCancellationRequested) { // Защита от переполнения памяти if (_writeTaskPool.TaskCount() > _maxTasks) { Thread.Sleep(_sleep); continue; } ITaskInfo taskInfo = _compressTaskPool.NextTask(); if (taskInfo == null) { Thread.Sleep(_sleep); continue; } _writeTaskPool.AddTask(_taskFactory.CreateWriteTaskInfo(taskInfo.GetId(), taskInfo.Execute(null) as byte[])); _lastZippedBlock++; } #if DEBUG Console.WriteLine("End of compressing"); #endif } catch (Exception exc) { Console.WriteLine("Error on file compressing"); #if DEBUG Console.WriteLine(exc); #endif } }
/// <summary> /// Метод для потока чтения. Чтение и генерация задач сжатия происходит в 1 поток, что даёт максимальную нагрузку на диск /// </summary> /// <param name="obj"> /// Дескриптор файла для чтения /// </param> private void ReadingThread(object obj) { FileDescriptor readFile = obj as FileDescriptor; _fileLength = readFile.GetDescription.Length; try { using (FileStream fileToBeDecompressed = readFile.GetDescription.OpenRead()) { // Читать блоки архива, пока не закончится файл while (fileToBeDecompressed.Position < _fileLength && !_cancellationToken.IsCancellationRequested) { _position = fileToBeDecompressed.Position; // Защита от переполнения памяти if (_compressTaskPool.TaskCount() > _maxTasks * _cores) { Thread.Sleep(_sleep); continue; } ITaskInfo task = _taskFactory.CreateReadTaskInfo(_batchCount, 0); _compressTaskPool.AddTask(_taskFactory.CreateProcessTaskInfo(_batchCount++, task.Execute(fileToBeDecompressed) as byte[])); } _isReading = false; #if DEBUG Console.WriteLine("End of reading"); #endif } } catch (Exception exc) { Console.WriteLine("Error on file reading"); #if DEBUG Console.WriteLine(exc); #endif } }