/// <summary> /// Метод для потока генерации задач для чтения. Необходим для более гибкого распределения нагрузки на поток чтения файла /// </summary> private void GeneratorThread() { try { int wait = Convert.ToInt32(Math.Pow(_cores, 1.5)); for (int i = 0; i < _batchCount; ++i) { // Защита от переполнения памяти // Без этого произойдёт переполнение // Нагенерируется больше задач, чем возможно обработать за промежуток времени, проверено на SSD // TODO: Возможно подобрать более оптимальные значения maxTasks за счёт градиентного спуска if (_readTaskPool.TaskCount() > _maxTasks) { --i; Thread.Sleep(_sleep); continue; } _readTaskPool.AddTask(_taskFactory.CreateReadTaskInfo(i, _readBlockSize)); } // Обработка последнего куска if (_batchCount < _totalCount) { _readTaskPool.AddTask(_taskFactory.CreateReadTaskInfo(_batchCount, _lastPiece)); } #if DEBUG Console.WriteLine("End of generating tasksInfos"); #endif } catch (Exception exc) { Console.WriteLine("Error on generating reading tasks"); #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 } }