public static async void Render(RenderPackModel renderPack, RenderActionsModel renderActionsPack,
                                        bool draftMode = true, bool @continue = false)
        {
            var renderId = ++_renderId;

            _sourceParallel?.Cancel();
            // _sourceParallel?.Token.ThrowIfCancellationRequested();
            _sourceDrawIntermediate?.Cancel();
            // _sourceDrawIntermediate?.Token.ThrowIfCancellationRequested();


            if (_sourceRender != null)
            {
                _sourceRender.Cancel(true);
                // _sourceRender.Token.ThrowIfCancellationRequested();
                await WaitForRenderEnd(TimeSpan.FromSeconds(10));

                _sourceRender = new CancellationTokenSource();
            }
            else
            {
                _sourceRender = new CancellationTokenSource();
            }

            if (renderId != _renderId)
            {
                return;
            }
            if (draftMode)
            {
                DestroyDisplay();
            }

            try
            {
                await Task.Run(() => RenderTask(renderPack, renderActionsPack, renderId, draftMode, @continue),
                               _sourceRender.Token);
            }
            catch (OperationCanceledException)
            {
                Debug.WriteLine($"# cancel of {renderId}");
            }
            finally
            {
                Debug.WriteLine($"# end of #{renderId}");
                _sourceRender?.Dispose();
                _sourceRender = null;
            }
        }
        private static void RenderTask(RenderPackModel renderPack, RenderActionsModel renderActionsPack, int renderId,
                                       bool draftMode = true, bool continueRender = false)
        {
            var rsm = PrepareRsm(renderPack, renderActionsPack, renderId, draftMode, continueRender);

            if (!draftMode)
            {
                renderActionsPack.ActionRenderState?.Invoke(StateRenderStarted, true);
            }
            IsRendering = true;

            if (rsm.RenderPack.RenderSettings.RenderByQuality)
            {
                RenderSequenceQuality(rsm);
            }
            else
            {
                RenderSequence(rsm);
            }
        }
        private static RenderSequenceModel PrepareRsm(RenderPackModel renderPack, RenderActionsModel renderActionsPack,
                                                      int renderId, bool draftMode = true, bool continueRender = false)
        {
            var cores    = Environment.ProcessorCount;
            var symmetry = renderPack.ViewSettings.Symmetry;
            var totalPointsPerIteration = renderPack.RenderSettings.ShotsPerIteration;
            var imageSize         = new Size(renderPack.ViewSettings.ImageWidth, renderPack.ViewSettings.ImageHeight);
            var renderColorMode   = renderPack.RenderSettings.RenderColorMode;
            var translationMatrix = Matrix.FromViewSettings(renderPack.ViewSettings);
            var colorCount        = renderPack.Transformations.Length;
            var iterators         = new IteratorModel[cores];

            for (var i = 0; i < cores; i++)
            {
                iterators[i] = new IteratorModel(renderPack);
            }
            var sector = Math.PI * 2.0 / symmetry;

            LogDisplayModel display;

            if (continueRender && HasRender)
            {
                display = Display;
            }
            else
            {
                display = new LogDisplayModel((int)imageSize.Width, (int)imageSize.Height,
                                              renderPack.Transformations.Length, renderPack.ViewSettings.BackColor);
            }
            display.RenderColorMode = renderColorMode;


            _transformationColors         = new Color[colorCount];
            _transformationGradientValues = new double[colorCount];
            for (var i = 0; i < colorCount; i++)
            {
                _transformationColors[i] = renderPack.Transformations[i].Color;
            }
            for (var i = 0; i < colorCount; i++)
            {
                _transformationGradientValues[i] = renderPack.Transformations[i].ColorPosition;
            }

            _gradModel = renderPack.GradModelCopy;

            var rsm = new RenderSequenceModel
            {
                TotalIterations       = renderPack.RenderSettings.Iterations,
                Cores                 = cores,
                Iterators             = iterators,
                TotalPointsPerCore    = totalPointsPerIteration / cores / symmetry,
                Symmetry              = symmetry,
                TranslationArray      = translationMatrix.Array,
                CenterPoint           = new Point(renderPack.ViewSettings.HalfWidth, renderPack.ViewSettings.HalfHeight),
                ImageSize             = imageSize,
                Display               = display,
                RenderActionsPack     = renderActionsPack,
                RenderId              = renderId,
                DraftMode             = draftMode,
                RenderPack            = renderPack,
                IsDrawingIntermediate = false,
                SectorCos             = Math.Cos(sector),
                SectorSin             = Math.Sin(sector)
            };

            return(rsm);
        }