/// <summary> /// Runs all puzzles found by the <see cref="Infrastructure.PuzzleLocator"/> and displays their output. /// </summary> public void Run() { var output = new ConcurrentBag <(PuzzleOutput sample, PuzzleOutput puzzle)>(); var sw = new Stopwatch(); var cts = new CancellationTokenSource(); CancellationToken token = cts.Token; // Give us 20s to run all tests, and bail after that. cts.CancelAfter(20_000); int completed = 0; var progressTask = Task.Run(() => AnsiConsole.Progress() .AutoClear(true) .Columns(new ProgressColumn[] { new TaskDescriptionColumn(), // Task description new ProgressBarColumn(), // Progress bar new SpinnerColumn(), // Spinner }) .Start(ctx => { ProgressTask task1 = ctx.AddTask("[blue]Vacationing in the tropics[/]"); task1.MaxValue = PuzzleLocator.Puzzles.Count - 100; task1.StartTask(); while (!ctx.IsFinished && !token.IsCancellationRequested) { double increment = completed - task1.Value; task1.Increment(increment); } }), token); sw.Start(); PuzzleLocator.Puzzles.ParallelForEachAsync(async(puzzleGenericType) => { dynamic puzzle = PuzzleFactory.Build(puzzleGenericType); string?name = puzzleGenericType?.FullName ?? "N/A"; output.Add( ( await RunAsync(name, () => puzzle.ValidateSample(), token), await RunAsync(name, () => puzzle.Solve(), token) )); Interlocked.Increment(ref completed); }).Wait(); sw.Stop(); progressTask.GetAwaiter().GetResult(); OutputRenderer.RenderResults(output); AnsiConsole.Console.MarkupLine($"[yellow]Advent of Code 2020 - Total Run Time: [/][teal]{sw.ElapsedMilliseconds}ms[/]"); }
private static async Task <List <Recipe> > GetRecipes( CraftingQuery craftingQuery, ProgressTask progress ) { progress.StartTask(); try { return(await craftingQuery .GetRecipes( progress : new Progress <ICollectionContext>(ctx => UpdateProgress(ctx, progress)) ) .OrderByDescending(recipe => recipe.Id) .ToListAsync()); } finally { progress.StopTask(); } }
private static async Task <List <Item> > GetItems( IReadOnlyCollection <int> itemIds, ItemsQuery itemsQuery, ProgressTask progress ) { var items = new List <Item>(itemIds.Count); progress.StartTask(); await foreach (var item in itemsQuery.GetItemsByIds( itemIds, progress: new Progress <ICollectionContext>(ctx => UpdateProgress(ctx, progress)) )) { items.Add(item); } progress.StopTask(); return(items); }
/// <summary> /// Download the file at the specified uri /// </summary> /// <param name="client">The <see cref="HttpClient"/> used to download</param> /// <param name="fileUri">The file uri</param> /// <param name="outputStream">The output <see cref="Stream"/></param> /// <param name="progress">The <see cref="ProgressTask"/> to use</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/></param> /// <returns>A new awaitable <see cref="Task"/></returns> public static async Task DownloadAsync(this HttpClient client, string fileUri, Stream outputStream, ProgressTask progress, CancellationToken cancellationToken = default) { using (HttpResponseMessage response = await client.GetAsync(fileUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken)) { response.EnsureSuccessStatusCode(); progress.MaxValue(response.Content.Headers.ContentLength ?? 0); progress.StartTask(); var filename = fileUri.Substring(fileUri.LastIndexOf('/') + 1); using var contentStream = await response.Content.ReadAsStreamAsync(cancellationToken); var buffer = new byte[8192]; while (true) { var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken); if (bytesRead == 0) { break; } progress.Increment(bytesRead); await outputStream.WriteAsync(buffer, 0, bytesRead, cancellationToken); } } }