e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
101 lines
3.7 KiB
C#
101 lines
3.7 KiB
C#
//----------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//----------------------------------------------------------------
|
|
|
|
namespace System.Activities.Debugger
|
|
{
|
|
using System;
|
|
using System.Activities.Hosting;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq.Expressions;
|
|
using System.Runtime;
|
|
using System.Activities.Validation;
|
|
|
|
// DebugController, one is needed per ActivityExecutor.
|
|
[DebuggerNonUserCode]
|
|
class DebugController
|
|
{
|
|
WorkflowInstance host;
|
|
DebugManager debugManager; // Instantiated after first instrumentation is successful.
|
|
|
|
public DebugController(WorkflowInstance host)
|
|
{
|
|
this.host = host;
|
|
}
|
|
|
|
public void WorkflowStarted()
|
|
{
|
|
}
|
|
|
|
public void WorkflowCompleted()
|
|
{
|
|
if (this.debugManager != null)
|
|
{
|
|
this.debugManager.Exit();
|
|
this.debugManager = null;
|
|
}
|
|
}
|
|
|
|
public void ActivityStarted(ActivityInstance activityInstance)
|
|
{
|
|
if (!(activityInstance.Activity.RootActivity is Constraint)) // Don't debug an activity in a Constraint
|
|
{
|
|
EnsureActivityInstrumented(activityInstance, false);
|
|
this.debugManager.OnEnterState(activityInstance);
|
|
}
|
|
}
|
|
|
|
public void ActivityCompleted(ActivityInstance activityInstance)
|
|
{
|
|
if (!(activityInstance.Activity.RootActivity is Constraint)) // Don't debug an activity in a Constraint
|
|
{
|
|
EnsureActivityInstrumented(activityInstance, true);
|
|
this.debugManager.OnLeaveState(activityInstance);
|
|
}
|
|
}
|
|
|
|
// Lazy instrumentation.
|
|
// Parameter primeCurrentInstance specify whether priming (if needed) is done
|
|
// up to the current instance. Set this to true when calling this from an "...Completed"
|
|
// (exit state).
|
|
void EnsureActivityInstrumented(ActivityInstance instance, bool primeCurrentInstance)
|
|
{
|
|
if (this.debugManager == null)
|
|
{ // Workflow has not been instrumented yet.
|
|
|
|
// Finding rootInstance and check all referred sources.
|
|
Stack<ActivityInstance> ancestors = new Stack<ActivityInstance>();
|
|
while (instance.Parent != null)
|
|
{
|
|
ancestors.Push(instance);
|
|
instance = instance.Parent;
|
|
}
|
|
|
|
Activity rootActivity = instance.Activity;
|
|
|
|
// Do breakOnStartup only if debugger is attached from the beginning, i.e. no priming needed.
|
|
// This specified by change the last parameter below to: "(ancestors.Count == 0)".
|
|
this.debugManager = new DebugManager(rootActivity, "Workflow", "Workflow", "DebuggerThread", false, this.host, ancestors.Count == 0);
|
|
|
|
if (ancestors.Count > 0)
|
|
{
|
|
// Priming the background thread
|
|
this.debugManager.IsPriming = true;
|
|
while (ancestors.Count > 0)
|
|
{
|
|
ActivityInstance ancestorInstance = ancestors.Pop();
|
|
this.debugManager.OnEnterState(ancestorInstance);
|
|
}
|
|
if (primeCurrentInstance)
|
|
{
|
|
this.debugManager.OnEnterState(instance);
|
|
}
|
|
this.debugManager.IsPriming = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|