Permalink
Browse files

fix refresh bugs in CallStackPad

  • Loading branch information...
1 parent 070efb3 commit f5e15070885e8d92db8d70b4e42a5e8f2dec1afc @siegfriedpammer siegfriedpammer committed Mar 6, 2012
View
25 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 @@ internal void RefreshPad()
return;
}
- List<CallStackItem> items = new List<CallStackItem>();
+ var items = new ObservableCollection<CallStackItem>();
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 @@ CallStackItem CreateItem(StackFrame frame, bool showExternalMethods, ref bool la
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;
View
46 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 @@ public static void EnqueueWork(this Process process, Dispatcher dispatcher, Acti
}
);
}
+
+ public static void EnqueueForEach<T>(this Process process, Dispatcher dispatcher, IList<T> items, Action<T> work)
+ {
+ DebuggeeState debuggeeStateWhenEnqueued = process.DebuggeeState;
+
+ dispatcher.BeginInvoke(
+ DispatcherPriority.Normal,
+ (Action)delegate { ProcessItems(process, dispatcher, 0, items, work, debuggeeStateWhenEnqueued); }
+ );
+ }
+
+ static void ProcessItems<T>(Process process, Dispatcher dispatcher, int startIndex, IList<T> items, Action<T> 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

0 comments on commit f5e1507

Please sign in to comment.