Skip to content

Commit

Permalink
Implement better progress reporting in ILSpy.
Browse files Browse the repository at this point in the history
  • Loading branch information
siegfriedpammer committed Oct 21, 2022
1 parent 9ff011c commit 4e1ed23
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 19 deletions.
35 changes: 23 additions & 12 deletions ILSpy/TextView/DecompilerTextView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ namespace ICSharpCode.ILSpy.TextView
/// Manages the TextEditor showing the decompiled code.
/// Contains all the threading logic that makes the decompiler work in the background.
/// </summary>
public sealed partial class DecompilerTextView : UserControl, IDisposable, IHaveState
public sealed partial class DecompilerTextView : UserControl, IDisposable, IHaveState, IProgress<DecompilationProgress>
{
readonly ReferenceElementGenerator referenceElementGenerator;
readonly UIElementGenerator uiElementGenerator;
Expand Down Expand Up @@ -540,18 +540,22 @@ void HighlightBrackets(object? sender, EventArgs e)
#endregion

#region RunWithCancellation
/// <summary>
/// Switches the GUI into "waiting" mode, then calls <paramref name="taskCreation"/> to create
/// the task.
/// When the task completes without being cancelled, the <paramref name="taskCompleted"/>
/// callback is called on the GUI thread.
/// When the task is cancelled before completing, the callback is not called; and any result
/// of the task (including exceptions) are ignored.
/// </summary>
[Obsolete("RunWithCancellation(taskCreation).ContinueWith(taskCompleted) instead")]
public void RunWithCancellation<T>(Func<CancellationToken, Task<T>> taskCreation, Action<Task<T>> taskCompleted)
public void Report(DecompilationProgress value)
{
RunWithCancellation(taskCreation).ContinueWith(taskCompleted, CancellationToken.None, TaskContinuationOptions.NotOnCanceled, TaskScheduler.FromCurrentSynchronizationContext());
double v = (double)value.UnitsCompleted / value.TotalUnits;
Dispatcher.BeginInvoke(DispatcherPriority.Normal, delegate {
progressBar.IsIndeterminate = !double.IsFinite(v);
progressBar.Value = v * 100.0;
progressTitle.Text = !string.IsNullOrWhiteSpace(value.Title) ? value.Title : Properties.Resources.Decompiling;
progressText.Text = value.Status;
progressText.Visibility = !string.IsNullOrWhiteSpace(progressText.Text) ? Visibility.Visible : Visibility.Collapsed;
var taskBar = MainWindow.Instance.TaskbarItemInfo;
if (taskBar != null)
{
taskBar.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal;
taskBar.ProgressValue = v;
}
});
}

/// <summary>
Expand All @@ -566,7 +570,10 @@ public Task<T> RunWithCancellation<T>(Func<CancellationToken, Task<T>> taskCreat
waitAdorner.Visibility = Visibility.Visible;
// Work around a WPF bug by setting IsIndeterminate only while the progress bar is visible.
// https://github.com/icsharpcode/ILSpy/issues/593
progressTitle.Text = Properties.Resources.Decompiling;
progressBar.IsIndeterminate = true;
progressText.Text = null;
progressText.Visibility = Visibility.Collapsed;
waitAdorner.BeginAnimation(OpacityProperty, new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(0.5)), FillBehavior.Stop));
var taskBar = MainWindow.Instance.TaskbarItemInfo;
if (taskBar != null)
Expand Down Expand Up @@ -605,6 +612,8 @@ public Task<T> RunWithCancellation<T>(Func<CancellationToken, Task<T>> taskCreat
currentCancellationTokenSource = null;
waitAdorner.Visibility = Visibility.Collapsed;
progressBar.IsIndeterminate = false;
progressText.Text = null;
progressText.Visibility = Visibility.Collapsed;
var taskBar = MainWindow.Instance.TaskbarItemInfo;
if (taskBar != null)
{
Expand Down Expand Up @@ -828,6 +837,7 @@ Task DoDecompile(DecompilationContext context, int outputLengthLimit)
return RunWithCancellation(
delegate (CancellationToken ct) { // creation of the background task
context.Options.CancellationToken = ct;
context.Options.Progress = this;
decompiledNodes = context.TreeNodes;
return DecompileAsync(context, outputLengthLimit);
})
Expand Down Expand Up @@ -1091,6 +1101,7 @@ Task<AvalonEditTextOutput> SaveToDiskAsync(DecompilationContext context, string
{
bool originalProjectFormatSetting = context.Options.DecompilerSettings.UseSdkStyleProjectFormat;
context.Options.EscapeInvalidIdentifiers = true;
context.Options.Progress = this;
AvalonEditTextOutput output = new AvalonEditTextOutput {
EnableHyperlinks = true,
Title = string.Join(", ", context.TreeNodes.Select(n => n.Text))
Expand Down
21 changes: 14 additions & 7 deletions ILSpy/TextView/DecompilerTextView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
folding:FoldingMargin.FoldingMarkerBackgroundBrush="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
folding:FoldingMargin.SelectedFoldingMarkerBackgroundBrush="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
folding:FoldingMargin.FoldingMarkerBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"
folding:FoldingMargin.SelectedFoldingMarkerBrush="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
>
folding:FoldingMargin.SelectedFoldingMarkerBrush="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}">
<ae:TextEditor.Resources>
<!-- prevent App-wide button style from applying to the buttons in the search box -->
<Style TargetType="{x:Type Button}">
Expand Down Expand Up @@ -78,11 +77,19 @@
</ae:TextEditor.Template>
</ae:TextEditor>
<Border Name="waitAdorner" Background="{StaticResource waitAdornerBackgoundBrush}" Visibility="Collapsed">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock FontSize="14pt" Text="{x:Static properties:Resources.Decompiling}"/>
<ProgressBar Name="progressBar" Height="16" Margin="0, 4" />
<Button Click="CancelButton_Click" HorizontalAlignment="Center" Content="{x:Static properties:Resources.Cancel}"/>
</StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Name="progressTitle" FontSize="14pt" Text="{x:Static properties:Resources.Decompiling}" Margin="3"/>
<ProgressBar Name="progressBar" Height="16" />
<TextBlock Name="progressText" Visibility="Collapsed" Margin="3" />
<Button Click="CancelButton_Click" HorizontalAlignment="Center" Margin="3" Content="{x:Static properties:Resources.Cancel}"/>
</StackPanel>
</Grid>
</Border>
</Grid>
</Border>
Expand Down

0 comments on commit 4e1ed23

Please sign in to comment.