コード例 #1
0
 Task DoDecompile(DecompilationContext context, int outputLengthLimit)
 {
     return(RunWithCancellation(
                delegate(CancellationToken ct) {           // creation of the background task
         context.Options.CancellationToken = ct;
         return DecompileAsync(context, outputLengthLimit);
     })
            .Then(
                delegate(AvaloniaEditTextOutput textOutput) {           // handling the result
         ShowOutput(textOutput, context.Language.SyntaxHighlighting, context.Options.TextViewState);
         decompiledNodes = context.TreeNodes;
     })
            .Catch <Exception>(exception => {
         textEditor.SyntaxHighlighting = null;
         Debug.WriteLine("Decompiler crashed: " + exception.ToString());
         AvaloniaEditTextOutput output = new AvaloniaEditTextOutput();
         if (exception is OutputLengthExceededException)
         {
             WriteOutputLengthExceededMessage(output, context, outputLengthLimit == DefaultOutputLengthLimit);
         }
         else
         {
             output.WriteLine(exception.ToString());
         }
         ShowOutput(output);
         decompiledNodes = context.TreeNodes;
     }));
 }
コード例 #2
0
        Task <AvaloniaEditTextOutput> SaveToDiskAsync(DecompilationContext context, string fileName)
        {
            TaskCompletionSource <AvaloniaEditTextOutput> tcs = new TaskCompletionSource <AvaloniaEditTextOutput>();
            Thread thread = new Thread(new ThreadStart(
                                           delegate {
                try {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    using (StreamWriter w = new StreamWriter(fileName)) {
                        try {
                            DecompileNodes(context, new PlainTextOutput(w));
                        } catch (OperationCanceledException) {
                            w.WriteLine();
                            w.WriteLine("Decompiled was cancelled.");
                            throw;
                        }
                    }
                    stopwatch.Stop();
                    AvaloniaEditTextOutput output = new AvaloniaEditTextOutput();
                    output.WriteLine("Decompilation complete in " + stopwatch.Elapsed.TotalSeconds.ToString("F1") + " seconds.");
                    output.WriteLine();
                    output.AddButton(null, "Open Explorer", delegate { Process.Start("explorer", "/select,\"" + fileName + "\""); });
                    output.WriteLine();
                    tcs.SetResult(output);
                } catch (OperationCanceledException) {
                    tcs.SetCanceled();
#if DEBUG
                } catch (AggregateException ex) {
                    tcs.SetException(ex);
#else
                } catch (Exception ex) {
                    tcs.SetException(ex);
#endif
                }
            }));

            thread.Start();
            return(tcs.Task);
        }
コード例 #3
0
 /// <summary>
 /// Starts the decompilation of the given nodes.
 /// The result will be saved to the given file name.
 /// </summary>
 void SaveToDisk(DecompilationContext context, string fileName)
 {
     RunWithCancellation(
         delegate(CancellationToken ct) {
         context.Options.CancellationToken = ct;
         return(SaveToDiskAsync(context, fileName));
     })
     .Then(output => ShowOutput(output))
     .Catch((Exception ex) => {
         textEditor.SyntaxHighlighting = null;
         Debug.WriteLine("Decompiler crashed: " + ex.ToString());
         // Unpack aggregate exceptions as long as there's only a single exception:
         // (assembly load errors might produce nested aggregate exceptions)
         AvaloniaEditTextOutput output = new AvaloniaEditTextOutput();
         output.WriteLine(ex.ToString());
         ShowOutput(output);
     }).HandleExceptions();
 }
コード例 #4
0
        /// <summary>
        /// Switches the GUI into "waiting" mode, then calls <paramref name="taskCreation"/> to create
        /// the task.
        /// If another task is started before the previous task finishes running, the previous task is cancelled.
        /// </summary>
        public Task <T> RunWithCancellation <T>(Func <CancellationToken, Task <T> > taskCreation)
        {
            if (waitAdorner.IsVisible != true)
            {
                waitAdorner.IsVisible = true;
                // Work around a WPF bug by setting IsIndeterminate only while the progress bar is visible.
                // https://github.com/icsharpcode/ILSpy/issues/593
                progressBar.IsIndeterminate = true;

                waitAdorner.Opacity = 1;
                //TODO: animation
                //waitAdorner.BeginAnimation(OpacityProperty, new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(0.5)), FillBehavior.Stop));

                // TODO: taskbar progress
                //var taskBar = MainWindow.Instance.TaskbarItemInfo;
                //if (taskBar != null) {
                //	taskBar.ProgressState = Avalonia.Shell.TaskbarItemProgressState.Indeterminate;
                //}
            }
            CancellationTokenSource previousCancellationTokenSource = currentCancellationTokenSource;
            var myCancellationTokenSource = new CancellationTokenSource();

            currentCancellationTokenSource = myCancellationTokenSource;
            // cancel the previous only after current was set to the new one (avoid that the old one still finishes successfully)
            if (previousCancellationTokenSource != null)
            {
                previousCancellationTokenSource.Cancel();
            }

            var      tcs = new TaskCompletionSource <T>();
            Task <T> task;

            try {
                task = taskCreation(myCancellationTokenSource.Token);
            } catch (OperationCanceledException) {
                task = TaskHelper.FromCancellation <T>();
            } catch (Exception ex) {
                task = TaskHelper.FromException <T>(ex);
            }
            Action continuation = delegate {
                try {
                    if (currentCancellationTokenSource == myCancellationTokenSource)
                    {
                        currentCancellationTokenSource = null;
                        waitAdorner.IsVisible          = false;
                        progressBar.IsIndeterminate    = false;
                        // TODO: taskbar progress
                        //var taskBar = MainWindow.Instance.TaskbarItemInfo;
                        //if (taskBar != null) {
                        //	taskBar.ProgressState = TaskbarItemProgressState.None;
                        //}
                        if (task.IsCanceled)
                        {
                            AvaloniaEditTextOutput output = new AvaloniaEditTextOutput();
                            output.WriteLine("The operation was canceled.");
                            ShowOutput(output);
                        }
                        tcs.SetFromTask(task);
                    }
                    else
                    {
                        tcs.SetCanceled();
                    }
                } finally {
                    myCancellationTokenSource.Dispose();
                }
            };

            task.ContinueWith(delegate { Dispatcher.UIThread.InvokeAsync(continuation, DispatcherPriority.Normal); });
            return(tcs.Task);
        }