예제 #1
0
        static ExitStatus Run(BinaryReader sourceReader, BinaryWriter destinationWriter, IPackerEngine packer,
                              PackerMode packerMode, int blockLength, int parallelismDegree, CancellationTokenSource token, ILoggable logger)
        {
            int       blocksNumber = (int)Math.Ceiling((double)sourceReader.BaseStream.Length / blockLength);
            Stopwatch watcher      = new Stopwatch();

            watcher.Start();
            logger?.LogMessage("Parallel Packer started:");
            logger?.LogMessage($"    {packerMode.ToString().ToLower()}ing...");
            try {
                if (packerMode == PackerMode.Unpack)  // we should save blockLength into the packed file because of blockLength parameter can be shanged
                {
                    (blocksNumber, blockLength) = BinaryBlockReader.ReadBlockInfo(sourceReader);
                }

                var commonSourceConveyer      = new LockableConveyer <Block>();
                var commonDestinationConveyer = new LockableConveyer <Block>();

                var workers = new List <IWorkable> {
                    WorkerFactory.CreateSourceWorker(sourceReader, blocksNumber, blockLength, packerMode, commonSourceConveyer, logger),
                    WorkerFactory.CreateDestinationWorker(destinationWriter, blocksNumber, blockLength, packerMode, commonDestinationConveyer, logger)
                };
                for (int index = 1; index <= parallelismDegree; ++index)
                {
                    workers.Add(WorkerFactory.CreatePackerWorker(index, packerMode, packer, commonSourceConveyer, commonDestinationConveyer, logger));
                }

                WorkerFactory.DoWork(workers, token);

                watcher.Stop();
                if (token.IsCancellationRequested)
                {
                    logger?.LogMessage($"{packerMode}ing has been cancelled by user '{Environment.UserName}' after {watcher.Elapsed}");
                    return(ExitStatus.CANCEL);
                }
                else
                {
                    logger?.LogMessage($"{packerMode}ing has been finished successfully in {watcher.Elapsed}:");
                    logger?.LogMessage($"    total blocks number: {blocksNumber}");
                    logger?.LogMessage($"    raw block length: {blockLength}");
                    return(ExitStatus.SUCCESS);
                }
            } catch (Exception e) {
                watcher.Stop();
                logger?.LogError($"{packerMode}ing finished with ERRORS in {watcher.Elapsed}:", e);
                return(ExitStatus.ERROR);
            }
        }