public UBitmap Generate2DInFourThreadsSync(PlanetContainer planetContainer, Action<float> callBack, CancellationToken token)
        {
            const int CORES = 4;

            var container = planetContainer.Container2D;

            __StartTime = DateTime.Now;

            var genTasks = new Task[CORES];
            var bmps = new UColor[CORES][,];

            var pg = new PlanetGeneratorNative[CORES];

            var percents = new float[CORES];

            const int PICTURE_SHIFT = 2;

            var w = container.Width / 2 + PICTURE_SHIFT;
            var h = container.Height / 2 + PICTURE_SHIFT;

            var resultBitmap = new UColor[container.Width, container.Height];

            for (int i = 0; i < CORES; i++)
            {
                var index = i;
                genTasks[i] = new Task(() =>
                {
                    pg[index] = new PlanetGeneratorNative(AlgorithmType.Classic);

                    pg[index].OnProgressChange = p =>
                    {
                        percents[index] = p;

                        callBack?.Invoke(percents.Sum() / CORES);
                    };

                    var lx = w * (index / 2);
                    var ly = h * (index % 2);

                    if (lx > 0)
                        lx -= PICTURE_SHIFT;

                    if (ly > 0)
                        ly -= PICTURE_SHIFT;

                    var uBmp = pg[index].Generate(planetContainer, token, lx, ly, w, h);
                    if (token.IsCancellationRequested)
                        return;
                    var tmpBmp = uBmp.Map;
                    bmps[index] = tmpBmp;
                }, token);
            }

            for (int i = 0; i < CORES; i++)
                genTasks[i].Start();

            Task.WaitAll(genTasks);

            if (token.IsCancellationRequested)
                return null;

            for (int i = 0; i < CORES; i++)
            {
                var lw = w - PICTURE_SHIFT;
                var lh = h - PICTURE_SHIFT;

                var lx = (i / 2) * lw;
                var ly = (i % 2) * lh;

                var dx = lx > 0 ? PICTURE_SHIFT : 0;
                var dy = ly > 0 ? PICTURE_SHIFT : 0;

                for (int x = 0; x < lw; x++)
                    for (int y = 0; y < lh; y++)
                        resultBitmap[lx + x, ly + y] = bmps[i][x + dx, y + dy];
            }

            return new UBitmap(resultBitmap);
        }
        private UBitmap Generate2DInOneThread(PlanetContainer planetContainer, Action<float> callBack, CancellationToken token)
        {
            var pc = planetContainer;
            var generator = new PlanetGeneratorNative(pc.Algorithm);

            generator.OnProgressChange += callBack;

            return generator.Generate(pc, token);
        }