private byte[] Generator2(Difficulty dif, Nullable <CancellationToken> cancelToken, IProgress <GenerateProgressArgs> progress)
        {
            byte[][] boards = new byte[5][];

            int tryNum = 0;

            GenerateProgressArgs args = new GenerateProgressArgs();

            var genProg = new Progress <int>(value => args.Progress[0] = value);
            IProgress <TryArgs> tryProg = new Progress <TryArgs>(value => { args.TryNum = value.TryNum; args.TryStatus = value.TryStatus; });

            int tryTime = 5;

            if ((int)dif > 56)
            {
                tryTime += ((int)dif % 56) * 2;
            }

            Timer reporter = new Timer((e) => progress?.Report(args), null, 0, 200);

            while (true)
            {
                if (cancelToken != null ? cancelToken.Value.IsCancellationRequested : false)
                {
                    reporter.Dispose();
                    return(null);
                }

                CancellationTokenSource tokenSource = new CancellationTokenSource();
                var token = tokenSource.Token;

                if (cancelToken != null)
                {
                    Task.Factory.StartNew(() => { while (!cancelToken.Value.IsCancellationRequested)
                                                  {
                                                      ;
                                                  }
                                                  tokenSource.Cancel(); }, token);
                }

                tryNum++;

                Task <bool>[] taskes = new Task <bool> [5];

                for (int i = 0; i < 5; i++)
                {
                    taskes[i] = Task.Run(() => Gen3Async(dif, out boards[i], token, tryNum, genProg));
                }

                Task.Factory.StartNew(() => { Task.Delay(TimeSpan.FromSeconds(tryTime)); tokenSource.Cancel(); }, token);



                var finishedIndex = Task.WaitAny(taskes);

                tryProg.Report(new TryArgs(tryNum, taskes[finishedIndex].Result));

                tokenSource.Cancel();
                tokenSource.Dispose();

                if (taskes[finishedIndex].Result)
                {
                    reporter.Dispose();
                    progress?.Report(args);
                    return(boards[finishedIndex]);
                }
            }
        }
        private byte[] Generator(Difficulty dif, Nullable <CancellationToken> cancelToken, IProgress <GenerateProgressArgs> progress)
        {
            CancellationTokenSource tokenSource = new CancellationTokenSource();
            var token = tokenSource.Token;

            byte[] board1    = null;
            byte[] board2    = null;
            byte[] board3    = null;
            byte[] board4    = null;
            byte[] board5    = null;
            bool   finished1 = false;
            bool   finished2 = false;
            bool   finished3 = false;
            bool   finished4 = false;
            bool   finished5 = false;

            DateTime priv = DateTime.Now;
            DateTime now;
            double   dt      = 0;
            double   time    = 0;
            double   tikTime = 0;
            int      tryNum  = 1;

            GenerateProgressArgs args = new GenerateProgressArgs();

            var genProg = new Progress <int>(value => args.Progress[1] = value);
            var tryProg = new Progress <TryArgs>(value => { args.TryNum = value.TryNum; args.TryStatus = value.TryStatus; });

            int tryTime = 5;

            if ((int)dif > 56)
            {
                tryTime += ((int)dif % 56) * 2;
            }

            Task gen1 = new Task(() => finished1 = Gen2Async(dif, out board1, token, tryNum, genProg, tryProg));
            Task gen2 = new Task(() => finished2 = Gen2Async(dif, out board2, token, tryNum, genProg, tryProg));
            Task gen3 = new Task(() => finished3 = Gen2Async(dif, out board3, token, tryNum, genProg, tryProg));
            Task gen4 = new Task(() => finished4 = Gen2Async(dif, out board4, token, tryNum, genProg, tryProg));
            Task gen5 = new Task(() => finished5 = Gen2Async(dif, out board5, token, tryNum, genProg, tryProg));

            gen1.Start();
            gen2.Start();
            gen3.Start();
            gen4.Start();
            gen5.Start();
            while (!(finished1 || finished2 || finished3 || finished4 || finished5))
            {
                now      = DateTime.Now;
                dt       = (now - priv).TotalSeconds;
                priv     = now;
                time    += dt;
                tikTime += dt;

                if (tikTime > 0.02)
                {
                    progress?.Report(args);
                    tikTime = 0;
                }

                if (time > tryTime)
                {
                    time = 0;
                    tokenSource.Cancel();
                    tokenSource.Dispose();
                    tokenSource = new CancellationTokenSource();
                    token       = tokenSource.Token;
                    tryNum++;
                    gen1 = new Task(() => finished1 = Gen2Async(dif, out board1, token, tryNum, genProg, tryProg));
                    gen2 = new Task(() => finished2 = Gen2Async(dif, out board2, token, tryNum, genProg, tryProg));
                    gen3 = new Task(() => finished3 = Gen2Async(dif, out board3, token, tryNum, genProg, tryProg));
                    gen4 = new Task(() => finished4 = Gen2Async(dif, out board4, token, tryNum, genProg, tryProg));
                    gen5 = new Task(() => finished5 = Gen2Async(dif, out board5, token, tryNum, genProg, tryProg));
                    gen1.Start();
                    gen2.Start();
                    gen3.Start();
                    gen4.Start();
                    gen5.Start();
                }


                if (cancelToken != null ? cancelToken.Value.IsCancellationRequested : false)
                {
                    tokenSource.Cancel();
                    tokenSource.Dispose();
                    return(null);
                }
            }
            progress?.Report(args);

            tokenSource.Cancel();
            tokenSource.Dispose();

            if (finished1)
            {
                return(board1);
            }
            if (finished2)
            {
                return(board2);
            }
            if (finished3)
            {
                return(board3);
            }
            if (finished4)
            {
                return(board4);
            }
            if (finished5)
            {
                return(board5);
            }
            return(null);
        }
示例#3
0
        public Task <byte[]> GenerateAsync(int difficulty, int numParalalTrys, int tryPeriod, IProgress <GenerateProgressArgs> progress = null, IProgress <LegalBoardProgressArgs> legalBoardProgress = null, CancellationToken?token = null)
        {
            return(Task.Run(() =>
            {
                var finders = new Task <byte[]> [numParalalTrys];

                var args = new GenerateProgressArgs(numParalalTrys);
                for (int i = 0; i < args.ProgStats.Length; i++)
                {
                    args.ProgStats[i] = new int[difficulty];
                }
                var legalBoardArgs = new LegalBoardProgressArgs(numParalalTrys);

                var genProg = new Progress <int> [numParalalTrys];
                var boardProg = new Progress <byte[]> [numParalalTrys];
                var progStat = new Progress <ProgArg> [numParalalTrys];
                var holder = new ProgressRefHolder[numParalalTrys];

                for (int j = 0; j < genProg.Length; j++)
                {
                    var an = new { number = j };
                    genProg[j] = new Progress <int>((value) =>
                    {
                        args.Progress[an.number] = legalBoardArgs.EmptyCells[an.number] = value;
                        legalBoardArgs.Legal[an.number] = false;
                    });
                    boardProg[j] = new Progress <byte[]>((value) =>
                    {
                        legalBoardArgs.Boards[an.number] = value;
                        legalBoardArgs.Legal[an.number] = true;
                        legalBoardProgress?.Report(legalBoardArgs);
                    });
                    progStat[j] = new Progress <ProgArg>((value) => {
                        args.ProgStats[an.number][value.Current] = value.AllReadyTryed;
                    });
                    holder[j] = new ProgressRefHolder()
                    {
                        BoardProgress = boardProg[j], CellProgress = genProg[j], ProgStats = progStat[j]
                    };
                }

                IProgress <TryArgs> tryProg = new Progress <TryArgs>(value => { args.TryNum = value.TryNum; args.TryStatus = value.TryStatus; });
                var tryNumber = 0;
                var tryArgs = new TryArgs(tryNumber, false);

                using (var reporter = new Timer((e) => (e as IProgress <GenerateProgressArgs>)?.Report(args), progress, 0, 10))
                {
                    while (true)
                    {
                        tryArgs.TryNum = ++tryNumber;
                        tryProg.Report(tryArgs);
                        using (var tokenSource = new CancellationTokenSource())
                        {
                            Timer checker = null;
                            if (token != null)
                            {
                                checker = new Timer((ts) => { if (token.Value.IsCancellationRequested)
                                                              {
                                                                  ((CancellationTokenSource)ts).Cancel(); token.Value.ThrowIfCancellationRequested();
                                                              }
                                                    }, tokenSource, 0, 1);
                            }


                            var token2 = tokenSource.Token;

                            Task <byte[]> resTask = null;
                            try
                            {
                                for (int i = 0; i < finders.Length; i++)
                                {
                                    var an = new { number = i };
                                    finders[i] = Task.Run(() =>
                                    {
                                        return GetLegalBoard2(difficulty,
                                                              holder[an.number].CellProgress,
                                                              holder[an.number].BoardProgress,
                                                              holder[an.number].ProgStats,
                                                              token2);
                                    }, token2);
                                }

                                tokenSource.CancelAfter(TimeSpan.FromSeconds(tryPeriod));

                                resTask = Task.WhenAny(finders).Result;
                            }
                            catch (OperationCanceledException)
                            {
                            }


                            tokenSource.Cancel();

                            if (resTask.Status == TaskStatus.RanToCompletion)
                            {
                                tryArgs.TryStatus = true;
                                tryProg.Report(tryArgs);
                                progress?.Report(args);
                                checker?.Dispose();
                                return resTask.Result;
                            }
                            checker?.Dispose();


                            Debug.WriteLine($"Failed! Attempt: {tryNumber}.");
                            Debug.WriteLine($"Disposed Token.");
                        }
                    }
                }
            }, token.Value));
        }