Browse Source

remove DoEvents from all debugger pads

pull/18/head
Siegfried Pammer 14 years ago
parent
commit
821ffcb805
  1. 93
      src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs
  2. 7
      src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/TreeNodeWrapper.cs
  3. 12
      src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs
  4. 2
      src/AddIns/Debugger/Debugger.AddIn/Pads/ObjectGraphPad.cs
  5. 10
      src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackPad.cs
  6. 7
      src/AddIns/Debugger/Debugger.AddIn/Pads/RunningThreadsPad.cs
  7. 55
      src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs
  8. 44
      src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs
  9. 21
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml.cs
  10. 2
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphWindow.xaml.cs

93
src/AddIns/Debugger/Debugger.AddIn/Pads/CallStackPad.xaml.cs

@ -147,66 +147,59 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -147,66 +147,59 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
return;
}
List<CallStackItem> items = null;
List<CallStackItem> items = new List<CallStackItem>();
using(new PrintTimes("Callstack refresh")) {
try {
Utils.DoEvents(debuggedProcess);
items = CreateItems().ToList();
} catch(AbortedBecauseDebuggeeResumedException) {
} catch(System.Exception) {
if (debuggedProcess == null || debuggedProcess.HasExited) {
// Process unexpectedly exited
} else {
throw;
}
bool showExternalMethods = DebuggingOptions.Instance.ShowExternalMethods;
bool lastItemIsExternalMethod = false;
foreach (StackFrame frame in debuggedProcess.SelectedThread.GetCallstack(100)) {
StackFrame f = frame;
debuggedProcess.EnqueueWork(
Dispatcher,
delegate {
items.AddIfNotNull(CreateItem(f, showExternalMethods, ref lastItemIsExternalMethod));
});
}
}
view.ItemsSource = items;
}
IEnumerable<CallStackItem> CreateItems()
CallStackItem CreateItem(StackFrame frame, bool showExternalMethods, ref bool lastItemIsExternalMethod)
{
bool showExternalMethods = DebuggingOptions.Instance.ShowExternalMethods;
bool lastItemIsExternalMethod = false;
CallStackItem item;
foreach (StackFrame frame in debuggedProcess.SelectedThread.GetCallstack(100)) {
CallStackItem item;
// line number
string lineNumber = string.Empty;
if (DebuggingOptions.Instance.ShowLineNumbers) {
if (frame.NextStatement != null)
lineNumber = frame.NextStatement.StartLine.ToString();
}
// show modules names
string moduleName = string.Empty;
if (DebuggingOptions.Instance.ShowModuleNames) {
moduleName = frame.MethodInfo.DebugModule.ToString();
}
if (frame.HasSymbols || showExternalMethods) {
// Show the method in the list
item = new CallStackItem() {
Name = GetFullName(frame), Language = "", Line = lineNumber, ModuleName = moduleName
};
lastItemIsExternalMethod = false;
item.Frame = frame;
} else {
// Show [External methods] in the list
if (lastItemIsExternalMethod) continue;
item = new CallStackItem() {
Name = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ExternalMethods"),
Language = ""
};
lastItemIsExternalMethod = true;
}
yield return item;
// line number
string lineNumber = string.Empty;
if (DebuggingOptions.Instance.ShowLineNumbers) {
if (frame.NextStatement != null)
lineNumber = frame.NextStatement.StartLine.ToString();
}
// show modules names
string moduleName = string.Empty;
if (DebuggingOptions.Instance.ShowModuleNames) {
moduleName = frame.MethodInfo.DebugModule.ToString();
}
if (frame.HasSymbols || showExternalMethods) {
// Show the method in the list
Utils.DoEvents(debuggedProcess);
item = new CallStackItem() {
Name = GetFullName(frame), Language = "", Line = lineNumber, ModuleName = moduleName
};
lastItemIsExternalMethod = false;
item.Frame = frame;
} else {
// Show [External methods] in the list
if (lastItemIsExternalMethod) return null;
item = new CallStackItem() {
Name = ResourceService.GetString("MainWindow.Windows.Debug.CallStack.ExternalMethods"),
Language = ""
};
lastItemIsExternalMethod = true;
}
return item;
}
internal static string GetFullName(StackFrame frame)

7
src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/TreeNodeWrapper.cs

@ -4,11 +4,13 @@ @@ -4,11 +4,13 @@
using System;
using System.Linq;
using System.Windows;
using System.Windows.Threading;
using Debugger.AddIn.TreeModel;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Gui.Pads;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Services;
using ICSharpCode.TreeView;
namespace Debugger.AddIn.Pads.Controls
@ -40,7 +42,8 @@ namespace Debugger.AddIn.Pads.Controls @@ -40,7 +42,8 @@ namespace Debugger.AddIn.Pads.Controls
protected override void LoadChildren()
{
if (Node.HasChildNodes) {
this.Children.AddRange(Node.ChildNodes.Select(node => node.ToSharpTreeNode()));
((WindowsDebugger)DebuggerService.CurrentDebugger).DebuggedProcess
.EnqueueWork(Dispatcher.CurrentDispatcher, () => Children.AddRange(Node.ChildNodes.Select(node => node.ToSharpTreeNode())));
}
}
}

12
src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
using System.Collections.ObjectModel;
using System.Windows.Threading;
using Debugger;
using Debugger.AddIn.Pads.Controls;
using Debugger.AddIn.TreeModel;
@ -63,13 +64,18 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -63,13 +64,18 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
using(new PrintTimes("Local Variables refresh")) {
try {
Utils.DoEvents(debuggedProcess);
StackFrame frame = debuggedProcess.GetCurrentExecutingFrame();
if (frame == null) return;
localVarList.WatchItems.Clear();
foreach (var item in new StackFrameNode(frame).ChildNodes) {
localVarList.WatchItems.Add(item.ToSharpTreeNode());
foreach (var n in new StackFrameNode(frame).ChildNodes) {
var node = n;
debuggedProcess.EnqueueWork(
Dispatcher.CurrentDispatcher,
delegate {
localVarList.WatchItems.Add(node.ToSharpTreeNode());
}
);
}
}
catch(AbortedBecauseDebuggeeResumedException) { }

2
src/AddIns/Debugger/Debugger.AddIn/Pads/ObjectGraphPad.cs

@ -49,7 +49,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -49,7 +49,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
this.objectGraphControl.Clear();
return;
}
this.objectGraphControl.Refresh();
this.objectGraphControl.RefreshView();
}
protected override void SelectProcess(Process process)

10
src/AddIns/Debugger/Debugger.AddIn/Pads/ParallelPad/ParallelStackPad.cs

@ -8,7 +8,7 @@ using System.Text; @@ -8,7 +8,7 @@ using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using Debugger;
using Debugger.AddIn.Pads.ParallelPad;
using Debugger.AddIn.TreeModel;
@ -78,8 +78,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -78,8 +78,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
try {
// create all simple ThreadStacks
foreach (Thread thread in debuggedProcess.Threads) {
Utils.DoEvents(debuggedProcess);
CreateThreadStack(thread);
var t = thread;
debuggedProcess.EnqueueWork(Dispatcher.CurrentDispatcher, () => CreateThreadStack(t));
}
}
catch(AbortedBecauseDebuggeeResumedException) { }
@ -509,12 +509,10 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -509,12 +509,10 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
result.Add(obj);
}
Utils.DoEvents(debuggedProcess);
// return null if we are dealing with a simple thread
return noTasks == 0 ? null : result;
}
Utils.DoEvents(debuggedProcess);
return result;
}

7
src/AddIns/Debugger/Debugger.AddIn/Pads/RunningThreadsPad.cs

@ -6,6 +6,7 @@ using System.Collections.ObjectModel; @@ -6,6 +6,7 @@ using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Threading;
using Debugger;
using Debugger.AddIn.Pads.Controls;
using Debugger.AddIn.Pads.ParallelPad;
@ -92,9 +93,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -92,9 +93,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
using(new PrintTimes("Threads refresh")) {
try {
foreach (Thread t in debuggedProcess.Threads) {
Utils.DoEvents(debuggedProcess);
AddThread(t);
foreach (var t in debuggedProcess.Threads) {
var thread = t;
debuggedProcess.EnqueueWork(Dispatcher.CurrentDispatcher, () => AddThread(thread));
}
} catch(AbortedBecauseDebuggeeResumedException) {
} catch(Exception) {

55
src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs

@ -8,6 +8,7 @@ using System.Linq; @@ -8,6 +8,7 @@ using System.Linq;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Threading;
using System.Xml.Serialization;
using Debugger;
using Debugger.AddIn;
@ -189,43 +190,37 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -189,43 +190,37 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
InvalidatePad();
}
TreeNodeWrapper UpdateNode(TreeNodeWrapper node)
{
try {
LoggingService.Info("Evaluating: " + (string.IsNullOrEmpty(node.Node.Name) ? "is null or empty!" : node.Node.Name));
var nodExpression = debugger.GetExpression(node.Node.Name);
//Value val = ExpressionEvaluator.Evaluate(nod.Name, nod.Language, debuggedProcess.SelectedStackFrame);
ExpressionNode valNode = new ExpressionNode(null, null, node.Node.Name, nodExpression);
return valNode.ToSharpTreeNode();
} catch (GetValueException) {
string error = String.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Watch.InvalidExpression}"), node.Node.Name);
ErrorInfoNode infoNode = new ErrorInfoNode(node.Node.Name, error);
return infoNode.ToSharpTreeNode();
}
}
protected override void RefreshPad()
{
if (debuggedProcess == null || debuggedProcess.IsRunning)
return;
using(new PrintTimes("Watch Pad refresh")) {
try {
Utils.DoEvents(debuggedProcess);
List<TreeNodeWrapper> nodes = new List<TreeNodeWrapper>();
foreach (var node in watchList.WatchItems.OfType<TreeNodeWrapper>()) {
try {
LoggingService.Info("Evaluating: " + (string.IsNullOrEmpty(node.Node.Name) ? "is null or empty!" : node.Node.Name));
var nodExpression = debugger.GetExpression(node.Node.Name);
//Value val = ExpressionEvaluator.Evaluate(nod.Name, nod.Language, debuggedProcess.SelectedStackFrame);
ExpressionNode valNode = new ExpressionNode(null, null, node.Node.Name, nodExpression);
nodes.Add(valNode.ToSharpTreeNode());
}
catch (GetValueException) {
string error = String.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Watch.InvalidExpression}"), node.Node.Name);
ErrorInfoNode infoNode = new ErrorInfoNode(node.Node.Name, error);
nodes.Add(infoNode.ToSharpTreeNode());
var nodes = watchList.WatchItems.OfType<TreeNodeWrapper>().ToArray();
watchList.WatchItems.Clear();
foreach (var n in nodes) {
var node = n;
debuggedProcess.EnqueueWork(
Dispatcher.CurrentDispatcher,
delegate {
watchList.WatchItems.Add(UpdateNode(node));
}
}
// rebuild list
watchList.WatchItems.Clear();
foreach (var node in nodes)
watchList.WatchItems.Add(node);
}
catch(AbortedBecauseDebuggeeResumedException) { }
catch(Exception ex) {
if (debuggedProcess == null || debuggedProcess.HasExited) {
// Process unexpectedly exited
} else {
MessageService.ShowException(ex);
}
);
}
}
}

44
src/AddIns/Debugger/Debugger.AddIn/TreeModel/Utils.cs

@ -3,7 +3,6 @@ @@ -3,7 +3,6 @@
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;
using System.Windows.Threading;
@ -17,26 +16,29 @@ namespace Debugger.AddIn.TreeModel @@ -17,26 +16,29 @@ namespace Debugger.AddIn.TreeModel
{
public static partial class Utils
{
/// <param name="process">Process on which to track debuggee state</param>
public static void DoEvents(Process process)
public static void EnqueueWork(this Process process, Dispatcher dispatcher, Action work)
{
WorkbenchSingleton.AssertMainThread();
if (process == null) return;
DebuggeeState oldState = process.DebuggeeState;
WpfDoEvents();
DebuggeeState newState = process.DebuggeeState;
if (oldState != newState) {
LoggingService.Info("Aborted because debuggee resumed");
throw new AbortedBecauseDebuggeeResumedException();
}
}
public static void WpfDoEvents()
{
WorkbenchSingleton.AssertMainThread();
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => frame.Continue = false));
Dispatcher.PushFrame(frame);
var debuggeeStateWhenEnqueued = process.DebuggeeState;
// Always ask the scheduler to do only one piece of work at a time
// - this might actually be completely ok as we are not waiting anywhere between thread
dispatcher.BeginInvoke(
DispatcherPriority.Background,
(Action)delegate {
// Check that the user has not stepped in the meantime - if he has, do not do anything at all
if (process.IsPaused && debuggeeStateWhenEnqueued == process.DebuggeeState) {
try {
// Do the work, this may recursively enqueue more work
work();
} catch(System.Exception ex) {
if (process == null || process.HasExited) {
// Process unexpectedly exited - silently ignore
} else {
MessageService.ShowException(ex);
}
}
}
}
);
}
}
@ -59,7 +61,7 @@ namespace Debugger.AddIn.TreeModel @@ -59,7 +61,7 @@ namespace Debugger.AddIn.TreeModel
public class PrintTime: IDisposable
{
string text;
Stopwatch stopwatch = new Stopwatch();
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
public PrintTime(string text)
{

21
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml.cs

@ -60,16 +60,13 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -60,16 +60,13 @@ namespace Debugger.AddIn.Visualizers.Graph
txtExpression.Text = string.Empty;
}
public void Refresh()
public void RefreshView()
{
debuggerService.DebuggedProcess.EnqueueWork(Dispatcher, () => Refresh());
}
void Refresh()
{
try {
Debugger.AddIn.TreeModel.Utils.DoEvents(debuggerService.DebuggedProcess);
} catch(AbortedBecauseDebuggeeResumedException) {
Log.Warn("Object graph - debuggee resumed, cancelling refresh.");
this.graphDrawer.ClearCanvas();
return;
}
ClearErrorMessage();
if (string.IsNullOrEmpty(txtExpression.Text)) {
this.graphDrawer.ClearCanvas();
@ -107,19 +104,19 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -107,19 +104,19 @@ namespace Debugger.AddIn.Visualizers.Graph
if (value == null) {
shownExpression = null;
txtExpression.Text = null;
Refresh();
RefreshView();
return;
}
if (shownExpression == null || value.PrettyPrint() != shownExpression.PrettyPrint()) {
txtExpression.Text = value.PrettyPrint();
Refresh();
RefreshView();
}
}
}
private void Inspect_Button_Click(object sender, RoutedEventArgs e)
{
this.Refresh();
RefreshView();
}
ObjectGraph RebuildGraph(string expression)

2
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphWindow.xaml.cs

@ -89,7 +89,7 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -89,7 +89,7 @@ namespace Debugger.AddIn.Visualizers.Graph
{
// on step or breakpoint hit
if (!debuggerService.IsProcessRunning) {
this.objectGraphControl.Refresh();
this.objectGraphControl.RefreshView();
}
}

Loading…
Cancel
Save