public override void Handle(ref TaskPool readPool, ref TaskPool writePool)
        {
            int blockNumber = -1;

            byte[] blockValue = null;

            while (true)
            {
                try
                {
                    if (!readPool.TryGet(out blockNumber, out blockValue))
                    {
                        return;
                    }

                    if (blockValue == null)
                    {
                        break;
                    }

                    byte[] decompressedBlock = ApplyGZip(blockValue);

                    if (!writePool.TrySet(blockNumber, decompressedBlock))
                    {
                        return;
                    }
                }
                catch (Exception e)
                {
                    _delete = true;
                    Terminate();
                    Console.WriteLine(e.Message);
                    return;
                }
            }
        }
        public override void WriteFile(string destination, ref TaskPool writePool)
        {
            try
            {
                FileInfo  fi    = new FileInfo(destination);
                DriveInfo drive = new DriveInfo(fi.Directory.Root.FullName);
                if (drive.DriveFormat == "FAT32" && _originLength > MAX_FILE_SIZE)
                {
                    throw new IOException("ERROR: недостаточно места на диске записи распакованного файла (ограничение FAT32)");
                }
            }
            catch (Exception e)
            {
                Terminate();
                Console.WriteLine(e.Message);
                return;
            }

            int counter = 0;

            int blockNumber = -1;

            byte[] blockValue = null;

            Dictionary <int, byte[]> buffer = new Dictionary <int, byte[]>();

            try
            {
                using var bw = new BinaryWriter(new FileStream(destination, FileMode.Create, FileAccess.Write, FileShare.None));
                while (true)
                {
                    if (!writePool.TryGet(out blockNumber, out blockValue))
                    {
                        return;
                    }

                    if (blockValue == null)
                    {
                        break;
                    }

                    buffer[blockNumber] = blockValue;

                    while (buffer.ContainsKey(counter))
                    {
                        bw.Write(buffer[counter]);
                        buffer.Remove(counter);

                        counter++;
                        ShowProgress((double)counter / _blockCount);

                        if (counter == _blockCount)
                        {
                            Terminate();
                            return;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                _delete = true;
                Terminate();
                Console.WriteLine(e.Message);
            }

            if (_delete)
            {
                try
                {
                    File.Delete(destination);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    return;
                }
            }
        }
        public override void WriteFile(string destination, ref TaskPool writePool)
        {
            int counter = 0;

            int blockNumber = -1;

            byte[] blockValue = null;

            try
            {
                using var binWriter = new BinaryWriter(new FileStream(destination, FileMode.Create, FileAccess.Write, FileShare.None));
                binWriter.Write(BitConverter.GetBytes(_sourceFileSize));
                binWriter.Write(BitConverter.GetBytes(_blockCount));

                while (true)
                {
                    if (!writePool.TryGet(out blockNumber, out blockValue))
                    {
                        return;
                    }

                    if (blockValue == null)
                    {
                        break;
                    }

                    try
                    {
                        binWriter.Write(BitConverter.GetBytes(blockNumber));
                        binWriter.Write(blockValue.Length);
                        binWriter.Write(blockValue);
                    }
                    catch (IOException e)
                    {
                        Terminate();
                        logger.Error("Writing is terminated ({0})", e.Message);
                        binWriter.Close();
                        File.Delete(destination);
                        return;
                    }

                    counter++;
                    ShowProgress((double)counter / _blockCount);

                    if (counter == _blockCount)
                    {
                        Terminate();
                    }
                }
            }
            catch (Exception e)
            {
                _delete = true;
                Terminate();
                logger.Warn(e.Message);
            }

            if (_delete)
            {
                try
                {
                    File.Delete(destination);
                }
                catch (Exception e)
                {
                    logger.Warn(e.Message);
                    return;
                }
            }
        }