private static void Main() { Console.Title = Assembly.GetExecutingAssembly().GetName().Name; Console.CursorVisible = true; Console.WriteLine(ConsoleTextBlocks.ShowWelcome("Welcome to Sudoku Solver!")); Console.WriteLine(); GetAvailableSudokuGrids(); Console.WriteLine(); while (true) { SudokuGrid grid; using (var selectedFile = ConsoleInteractions.ShowListAndSelectItem(USER_ABS_DIR_AVAILABLE_GRIDS, SudokuGridFile.Extension, Console.In, Console.Out)) { grid = SudokuGrid.FromBinary(selectedFile); } Console.WriteLine(); var solvingTask = new Task <bool>(() => { var gridSolver = new SudokuSolvingIterationAssumptionTechnique(grid); gridSolver.Solve(); gridSolver.ApplySolutionToGrid(); return(gridSolver.SolutionExists); }); var dottingTaskCTS = new CancellationTokenSource(); var dottingTask = new Task(() => ConsoleTextBlocks.ShowBlinkingDots(dottingTaskCTS.Token, Console.Out)); var outputTask = new Task(() => ShowSolution(grid)); var escapeTask = new Task <bool>(ConsoleInteractions.ShowEscapeQuestion); var checkingCorrectnessTask = new Task <bool>(grid.CheckCorrectness); checkingCorrectnessTask.ContinueWith((fin) => { if (fin.Result) { solvingTask.Start(); } else { Console.WriteLine(ConsoleTextMessages.IncorrectInitialConfiguration + "\n"); escapeTask.Start(); } }, TaskContinuationOptions.OnlyOnRanToCompletion); solvingTask.ContinueWith((fin) => dottingTaskCTS.Cancel(), TaskContinuationOptions.OnlyOnRanToCompletion); dottingTask.ContinueWith((fin) => { if (solvingTask.Result) { outputTask.Start(); } else { Console.WriteLine(ConsoleTextMessages.IncorrectInitialConfiguration + "\n"); escapeTask.Start(); } }, TaskContinuationOptions.OnlyOnRanToCompletion); outputTask.ContinueWith((fin) => escapeTask.Start(), TaskContinuationOptions.OnlyOnRanToCompletion); dottingTask.Start(); checkingCorrectnessTask.Start(); escapeTask.Wait(); if (escapeTask.Result) { break; } } }