Example #1
0
        /// <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
            }
        }