From f5e15070885e8d92db8d70b4e42a5e8f2dec1afc Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 6 Mar 2012 20:38:51 +0100 Subject: [PATCH] fix refresh bugs in CallStackPad --- .../Debugger.AddIn/Pads/CallStackPad.xaml.cs | 25 +++++----- .../Debugger.AddIn/TreeModel/Utils.cs | 46 ++++++++++++++++++- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs index 3ba79fe23e..b5ed9c3d72 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs @@ -3,12 +3,12 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; - using Debugger; using Debugger.AddIn.TreeModel; using ICSharpCode.Core; @@ -147,24 +147,21 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads return; } - List items = new List(); + var items = new ObservableCollection(); using(new PrintTimes("Callstack refresh")) { bool showExternalMethods = DebuggingOptions.Instance.ShowExternalMethods; - bool lastItemIsExternalMethod = false; + bool previousItemIsExternalMethod = false; - foreach (StackFrame frame in debuggedProcess.SelectedThread.GetCallstack(100)) { - StackFrame f = frame; - debuggedProcess.EnqueueWork( + debuggedProcess.EnqueueForEach( Dispatcher, - delegate { - items.AddIfNotNull(CreateItem(f, showExternalMethods, ref lastItemIsExternalMethod)); - }); - } + debuggedProcess.SelectedThread.GetCallstack(100), + f => items.AddIfNotNull(CreateItem(f, showExternalMethods, ref previousItemIsExternalMethod)) + ); } view.ItemsSource = items; } - CallStackItem CreateItem(StackFrame frame, bool showExternalMethods, ref bool lastItemIsExternalMethod) + CallStackItem CreateItem(StackFrame frame, bool showExternalMethods, ref bool previousItemIsExternalMethod) { CallStackItem item; @@ -187,16 +184,16 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads item = new CallStackItem() { Name = GetFullName(frame), Language = "", Line = lineNumber, ModuleName = moduleName }; - lastItemIsExternalMethod = false; + previousItemIsExternalMethod = false; item.Frame = frame; } else { // Show [External methods] in the list - if (lastItemIsExternalMethod) return null; + if (previousItemIsExternalMethod) return null; item = new CallStackItem() { Name = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ExternalMethods"), Language = "" }; - lastItemIsExternalMethod = true; + previousItemIsExternalMethod = true; } return item; diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs index bf0d0bad0b..90488e6d7e 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs @@ -2,10 +2,11 @@ // This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt) using System; -using System.Collections; +using System.Collections.Generic; using System.Reflection; using System.Windows.Forms; using System.Windows.Threading; + using Debugger.AddIn.Pads.Controls; using ICSharpCode.Core; using ICSharpCode.NRefactory.Ast; @@ -40,6 +41,49 @@ namespace Debugger.AddIn.TreeModel } ); } + + public static void EnqueueForEach(this Process process, Dispatcher dispatcher, IList items, Action work) + { + DebuggeeState debuggeeStateWhenEnqueued = process.DebuggeeState; + + dispatcher.BeginInvoke( + DispatcherPriority.Normal, + (Action)delegate { ProcessItems(process, dispatcher, 0, items, work, debuggeeStateWhenEnqueued); } + ); + } + + static void ProcessItems(Process process, Dispatcher dispatcher, int startIndex, IList items, Action work, DebuggeeState debuggeeStateWhenEnqueued) + { + var watch = new System.Diagnostics.Stopwatch(); + watch.Start(); + + for (int i = startIndex; i < items.Count; i++) { + int index = i; + if (process.IsPaused && debuggeeStateWhenEnqueued == process.DebuggeeState) { + try { + // Do the work, this may recursively enqueue more work + work(items[index]); + } catch (System.Exception ex) { + if (process == null || process.HasExited) { + // Process unexpectedly exited - silently ignore + } else { + MessageService.ShowException(ex); + } + break; + } + } + + // if we are too slow move to background + if (watch.ElapsedMilliseconds > 100) { + dispatcher.BeginInvoke( + DispatcherPriority.Background, + (Action)delegate { ProcessItems(process, dispatcher, index, items, work, debuggeeStateWhenEnqueued); } + ); + break; + } + } + } + } public class AbortedBecauseDebuggeeResumedException: System.Exception