protected virtual async Task Run(IMenu menu, IEnumerable <IMenu> path) { if (menu == null) { throw new ArgumentNullException("menu"); } var pageNumber = 0; await menu.Enter(new Context(this, path)); var pages = new PaginatedAsyncSequence <IMenuItem>(menu.Items); async Task ExecuteMenuItemAndRefresh(IMenuItem item) { var context = new Context(this, path); await ExecuteItem(item, context); if (context.MenuInvalidated) { await pages.DisposeAsync(); pages = new PaginatedAsyncSequence <IMenuItem>(menu.Items); } } try { do { options = CreateOptions(); var progressCancellation = new CancellationTokenSource(); var loaderCancellation = new CancellationTokenSource(); var progressTask = Task.Run(async() => { try { await Task.Delay(100, progressCancellation.Token); if (!progressCancellation.Token.IsCancellationRequested) { using (var progress = ((IMenuUserInterface)this).StartProgress("Loading... Press [Esc] to cancel")) { progress.SetIndeterminate(); var result = await((IMenuUserInterface)this).Select(null, r => (r.Type == PromptType.Cancel, r.Type), progressCancellation.Token); if (result == PromptType.Cancel) { loaderCancellation.Cancel(); } } } } catch (TaskCanceledException) { } }); Page <IMenuItem> page; try { page = await pages.GetPage(pageNumber, options.Count, loaderCancellation.Token); } finally { progressCancellation.Cancel(); await progressTask; } if (menu.ExecuteIfSingleItem && page.IsFirstPage && page.Count == 1) { await ExecuteMenuItemAndRefresh(page[0]); break; } Render(menu, page, null, path); var(choice, item) = await Prompt(page); if (choice == MenuChoice.Cancel) { if (await menu.CanExit(new Context(this, path))) { break; } else { continue; } } if (choice == MenuChoice.PreviousPage) { --pageNumber; continue; } if (choice == MenuChoice.NextPage) { ++pageNumber; continue; } if (choice == MenuChoice.Item) { Render(menu, page, item, path); Cons.WriteLine(); Cons.WriteLine("Running..."); Cons.WriteLine(); await ExecuteMenuItemAndRefresh(item); } }while (!menu.ShouldExit); } finally { await pages.DisposeAsync(); } }