public static async Task WaitWithProgress( this Task task, string caption, CancellationTokenSource cts = null) { var dialogCts = new CancellationTokenSource(); var dialog = new TaskDialog { Caption = caption, Content = string.Empty }; if (cts != null) { dialog.IsCancelable = true; dialog.CommonButtons = TaskDialogButtons.Cancel; } dialog.Controls.Add(new TaskDialogProgressBar { IsIndeterminate = true }); dialog.Closing += (s, e) => { if (e.Button == TaskDialogButtonId.Cancel) { dialogCts.Cancel(); cts?.Cancel(); } }; await Task.WhenAny(task, dialog.ShowModalDelayed(dialogCts.Token)); dialogCts.Cancel(); if (dialog.IsShown) { dialog.Abort(); } }
public static async Task <T> RunWithProgress <T>( string caption, string info, Func <CancellationToken, IProgress <ProgressDelta>, T> action, CancellationToken?cancellationToken = null, TimeSpan?progressUpdateInterval = null) { var dialogCts = new CancellationTokenSource(); var linkedCts = cancellationToken != null ? CancellationTokenSource.CreateLinkedTokenSource(dialogCts.Token, cancellationToken.Value) : dialogCts; var dialog = new TaskDialog { Caption = caption, Content = string.Empty }; if (cancellationToken != null) { dialog.IsCancelable = true; dialog.CommonButtons = TaskDialogButtons.Cancel; } dialog.Controls.Add(new TaskDialogProgressBar(0, 100, 0)); dialog.Closing += (s, e) => { if (e.Button == TaskDialogButtonId.Cancel) { linkedCts.Cancel(); } }; var progress = new PeriodicCumulativeProgress( progressUpdateInterval ?? TimeSpan.FromMilliseconds(100), x => { if (x.IsIndeterminate) { dialog.ProgressBar.IsIndeterminate = true; dialog.Content = $"{x.Delta} {info}"; } else { dialog.ProgressBar.IsIndeterminate = false; dialog.ProgressBar.Value = x.Completion(x.Delta); dialog.Content = $"{x.Delta}/{x.Total} {info}"; } }); using (dialogCts) using (cancellationToken != null ? linkedCts : null) using (progress) { var dialogTask = ShowModalDelayed(dialog, dialogCts.Token); var result = await Task.Run( () => action(linkedCts.Token, progress), linkedCts.Token); dialogCts.Cancel(); if (dialog.IsShown) { dialog.Abort(); } await dialogTask.IgnoreCancellation(); return(result); } }