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); }
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)); }