internal WorkItem CreateWorkItem(ActivityInstance completedInstance, ActivityExecutor executor) { // We use the property to guard against the virtual method call // since we don't need it in the common case if (this.NeedsToGatherOutputs) { this.GatherOutputs(completedInstance); } CompletionWorkItem workItem; if (this.checkForCancelation) { workItem = new CompletionWithCancelationCheckWorkItem(this, completedInstance); } else { workItem = executor.CompletionWorkItemPool.Acquire(); workItem.Initialize(this, completedInstance); } if (completedInstance.InstanceMap != null) { completedInstance.InstanceMap.AddEntry(workItem); } return workItem; }
public BookmarkCallbackWrapper(BookmarkCallback callback, ActivityInstance owningInstance, BookmarkOptions bookmarkOptions) : base(callback, owningInstance) { Fx.Assert(callback != null || bookmarkOptions == BookmarkOptions.None, "Either we have a callback or we only allow SingleFire, Blocking bookmarks."); this.Options = bookmarkOptions; }
void InternalExecute(NativeActivityContext context, ActivityInstance completedInstance) { CompensationExtension compensationExtension = context.GetExtension<CompensationExtension>(); if (compensationExtension == null) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.ConfirmWithoutCompensableActivity(this.DisplayName))); } CompensationToken token = Target.Get(context); CompensationTokenData tokenData = token == null ? null : compensationExtension.Get(token.CompensationId); Fx.Assert(tokenData != null, "CompensationTokenData must be valid"); if (tokenData.ExecutionTracker.Count > 0) { if (this.onChildConfirmed == null) { this.onChildConfirmed = new CompletionCallback(InternalExecute); } this.toConfirmToken.Set(context, new CompensationToken(tokenData.ExecutionTracker.Get())); Fx.Assert(Body != null, "Body must be valid"); context.ScheduleActivity(Body, this.onChildConfirmed); } }
protected override void GatherOutputs(ActivityInstance completedInstance) { if (completedInstance.Activity.HandlerOf != null) { IList<RuntimeDelegateArgument> runtimeArguments = completedInstance.Activity.HandlerOf.RuntimeDelegateArguments; LocationEnvironment environment = completedInstance.Environment; for (int i = 0; i < runtimeArguments.Count; i++) { RuntimeDelegateArgument runtimeArgument = runtimeArguments[i]; if (runtimeArgument.BoundArgument != null) { if (ArgumentDirectionHelper.IsOut(runtimeArgument.Direction)) { Location parameterLocation = environment.GetSpecificLocation(runtimeArgument.BoundArgument.Id); if (parameterLocation != null) { if (this.results == null) { this.results = new Dictionary<string, object>(); } this.results.Add(runtimeArgument.Name, parameterLocation.Value); } } } } } }
public void Initialize(ActivityInstance activityInstance, int nextArgumentIndex, IDictionary<string, object> argumentValueOverrides, Location resultLocation) { Fx.Assert(nextArgumentIndex > 0, "The nextArgumentIndex must be greater than 0 otherwise we will incorrectly set the sub-state when ResolveArguments completes"); base.Reinitialize(activityInstance); this.nextArgumentIndex = nextArgumentIndex; this.argumentValueOverrides = argumentValueOverrides; this.resultLocation = resultLocation; }
public FaultWorkItem(FaultCallbackWrapper callbackWrapper, Exception propagatedException, ActivityInstance propagatedFrom, ActivityInstanceReference originalExceptionSource) : base(callbackWrapper.ActivityInstance) { this.callbackWrapper = callbackWrapper; this.propagatedException = propagatedException; this.propagatedFrom = propagatedFrom; this.originalExceptionSource = originalExceptionSource; }
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); } }
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); } }
internal ActivityScheduledRecord(Guid instanceId, ActivityInstance instance, ActivityInfo child) : base(instanceId) { Fx.Assert(child != null, "Child activity cannot be null."); if (instance != null) { this.Activity = new ActivityInfo(instance); } this.Child = child; }
internal CancelRequestedRecord(Guid instanceId, ActivityInstance instance, ActivityInstance child) : base(instanceId) { Fx.Assert(child != null, "Child activity instance cannot be null."); if (instance != null) { this.Activity = new ActivityInfo(instance); } this.Child = new ActivityInfo(child); }
protected override void OnHasCompleted(NativeActivityContext context, ActivityInstance completedInstance) { base.OnHasCompleted(context, completedInstance); //HACK:重写并行节点满足条件退出逻辑 var e = context.GetExtension<ParallelExtension>(); e.Cancelled(context.GetChildren() .Where(o => o.ID != completedInstance.ID) .Select(o => o.ID) .ToArray()); }
public void Register(Location location, Activity activity, LocationReference locationOwner, ActivityInstance activityInstance) { Fx.Assert(location.CanBeMapped, "should only register mappable locations"); if (this.mappableLocations == null) { this.mappableLocations = new List<MappableLocation>(); } this.mappableLocations.Add(new MappableLocation(locationOwner, activity, activityInstance, location)); }
/// <summary> /// Called each time a work item is acquired from the pool /// </summary> /// <param name="parentInstance">The ActivityInstance containin the variable or argument that contains this expression</param> /// <param name="expressionActivity">The expression to evaluate</param> /// <param name="instanceId">The ActivityInstanceID to use for expressionActivity</param> /// <param name="resultLocation">Location where the result of expressionActivity should be placed</param> /// <param name="nextArgumentWorkItem">WorkItem to execute after this one</param> public void Initialize(ActivityInstance parentInstance, ActivityWithResult expressionActivity, long instanceId, Location resultLocation, ResolveNextArgumentWorkItem nextArgumentWorkItem) { this.Reinitialize(parentInstance); Fx.Assert(resultLocation != null, "We should only use this work item when we are resolving arguments/variables and therefore have a result location."); Fx.Assert(expressionActivity.IsFastPath, "Should only use this work item for fast path expressions"); this.expressionActivity = expressionActivity; this.instanceId = instanceId; this.resultLocation = resultLocation; this.nextArgumentWorkItem = nextArgumentWorkItem; }
internal FaultPropagationRecord(Guid instanceId, ActivityInstance source, ActivityInstance faultHandler, bool isFaultSource, Exception fault) : base(instanceId) { Fx.Assert(source != null, "Fault source cannot be null"); this.FaultSource = new ActivityInfo(source); if (faultHandler != null) { this.FaultHandler = new ActivityInfo(faultHandler); } this.IsFaultSource = isFaultSource; this.Fault = fault; this.Level = TraceLevel.Warning; }
protected internal override void Invoke(NativeActivityContext context, ActivityInstance completedInstance) { EnsureCallback(callbackType, callbackParameterTypes); DelegateCompletionCallback completionCallback = (DelegateCompletionCallback)this.Callback; IDictionary<string, object> returnValue = this.results; if (returnValue == null) { returnValue = ActivityUtilities.EmptyParameters; } completionCallback(context, completedInstance, returnValue); }
public Bookmark CreateBookmark(string name, BookmarkCallback callback, ActivityInstance owningInstance, BookmarkOptions options) { Bookmark toAdd = new Bookmark(name); if (this.bookmarks != null && this.bookmarks.ContainsKey(toAdd)) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.BookmarkAlreadyExists(name))); } AddBookmark(toAdd, callback, owningInstance, options); //Regular bookmarks are never important UpdateAllExclusiveHandles(toAdd, owningInstance); return toAdd; }
internal BookmarkResumptionRecord(Guid instanceId, Bookmark bookmark, ActivityInstance ownerInstance, object payload) : base(instanceId) { if (bookmark.Scope != null) { this.BookmarkScope = bookmark.Scope.Id; } if (bookmark.IsNamed) { this.BookmarkName = bookmark.Name; } this.Owner = new ActivityInfo(ownerInstance); this.Payload = payload; }
public WorkItem GenerateWorkItem(ActivityInstance completedInstance, ActivityExecutor executor) { if (this.callbackWrapper != null) { return this.callbackWrapper.CreateWorkItem(completedInstance, executor); } else { // Variable defaults and argument expressions always have a parent // and never have a CompletionBookmark if (completedInstance.State != ActivityInstanceState.Closed && completedInstance.Parent.HasNotExecuted) { completedInstance.Parent.SetInitializationIncomplete(); } return new EmptyWithCancelationCheckWorkItem(completedInstance.Parent, completedInstance); } }
// 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; } } }
internal ActivityInstanceReference(ActivityInstance activity) { this.activityInstance = activity; }
public virtual void hasStructure(ActivityInstance expected) { assertTreeMatch(expected, actual); }
public WorkItem GenerateWorkItem(Exception propagatedException, ActivityInstance propagatedFrom, ActivityInstanceReference originalExceptionSource) { return(this.callbackWrapper.CreateWorkItem(propagatedException, propagatedFrom, originalExceptionSource)); }
protected internal abstract void Invoke(NativeActivityContext context, ActivityInstance completedInstance);
public NotifyUnhandledExceptionAction(Exception exception, ActivityInstance source) { this.Exception = exception; this.Source = source; }
public static RequestedAction CreateNotifyUnhandledExceptionAction(Exception exception, ActivityInstance sourceInstance) { return(new NotifyUnhandledExceptionAction(exception, sourceInstance)); }
static Dictionary<string, object> GenerateLocals(ActivityInstance instance) { Dictionary<string, object> locals = new Dictionary<string, object>(); locals.Add("debugInfo", new DebugInfo(instance)); return locals; }
internal void DeclareHandle(LocationReference locationReference, Location location, ActivityInstance activityInstance) { _hasHandles = true; Declare(locationReference, location, activityInstance); }
public ActivityInstanceAssertThatClause(ActivityInstance actual) { this.actual = actual; }
bool TrackData(string name, int id, ActivityInstance currentInstance, ICollection<string> data, bool wildcard, ref Dictionary<string, object> trackedData) { if (wildcard || data.Contains(name)) { Location location = currentInstance.Environment.GetSpecificLocation(id); if (location != null) { if (trackedData == null) { trackedData = new Dictionary<string, object>(10); } string dataName = name ?? NameGenerator.Next(); trackedData[dataName] = location.Value; if (TD.TrackingDataExtractedIsEnabled()) { TD.TrackingDataExtracted(dataName, this.Activity.Name); } return true; } } return false; }
public static ActivityInstanceAssertThatClause assertThat(ActivityInstance actual) { return(new ActivityInstanceAssertThatClause(actual)); }
void OnBodyComplete(NativeActivityContext context, ActivityInstance completedInstance) { ScheduleCondition(context); }
private void RegisterLocation(Location location, LocationReference locationReference, ActivityInstance activityInstance) { if (location.CanBeMapped) { _hasMappableLocations = true; this.MappableObjectManager.Register(location, this.Definition, locationReference, activityInstance); } }
internal void Declare(LocationReference locationReference, Location location, ActivityInstance activityInstance) { Fx.Assert((locationReference.Id == 0 && _locations == null) || (locationReference.Id >= 0 && _locations != null && locationReference.Id < _locations.Length), "The environment should have been created with the appropriate capacity."); Fx.Assert(location != null, ""); RegisterLocation(location, locationReference, activityInstance); if (_locations == null) { Fx.Assert(_singleLocation == null, "We should not have had a single location if we are trying to declare one."); Fx.Assert(locationReference.Id == 0, "We should think the id is zero if we are setting the single location."); _singleLocation = location; } else { Fx.Assert(_locations[locationReference.Id] == null || _locations[locationReference.Id] is DummyLocation, "We should not have had a location at the spot we are replacing."); _locations[locationReference.Id] = location; } }
internal void DeclareTemporaryLocation <T>(LocationReference locationReference, ActivityInstance activityInstance, bool bufferGetsOnCollapse) where T : Location { Location locationToDeclare = new Location <T>(); locationToDeclare.SetTemporaryResolutionData(this, bufferGetsOnCollapse); this.Declare(locationReference, locationToDeclare, activityInstance); }
public void OnEnterState(Activity expression, ActivityInstance instance, LocationEnvironment environment) { if (this.EnsureInstrumented(expression)) { this.EnterState(GetOrCreateThreadId(expression, instance), expression, GenerateLocals(instance)); } }
protected internal virtual void assertTreeMatch(ActivityInstance expected, ActivityInstance actual) { bool treesMatch = isTreeMatched(expected, actual); if (!treesMatch) { Assert.fail("Could not match expected tree \n" + expected + " \n\n with actual tree \n\n " + actual); } }
// Create logical thread and bring its call stack to reflect call from // the root up to (but not including) the instance. // If the activity is an expression though, then the call stack will also include the instance // (since it is the parent of the expression). int CreateLogicalThread(Activity activity, ActivityInstance instance, bool primeCurrentInstance) { Stack<ActivityInstance> ancestors = null; if (!this.DebugStartedAtRoot) { ancestors = new Stack<ActivityInstance>(); if (activity != instance.Activity || primeCurrentInstance) { // This mean that activity is an expression and // instance is the parent of this expression. Fx.Assert(primeCurrentInstance || (activity is ActivityWithResult), "Expect an ActivityWithResult"); Fx.Assert(primeCurrentInstance || (activity.Parent == instance.Activity), "Argument Expression is not given correct parent instance"); if (primeCurrentInstance || !IsParallelActivity(instance.Activity)) { ancestors.Push(instance); } } ActivityInstance instanceParent = instance.Parent; while (instanceParent != null && !IsParallelActivity(instanceParent.Activity)) { ancestors.Push(instanceParent); instanceParent = instanceParent.Parent; } if (instanceParent != null && IsParallelActivity(instanceParent.Activity)) { // Ensure thread is created for the parent (a Parallel activity). int parentThreadId = GetExecutingThreadId(instanceParent.Activity, false); if (parentThreadId < 0) { parentThreadId = CreateLogicalThread(instanceParent.Activity, instanceParent, true); Fx.Assert(parentThreadId > 0, "Parallel main thread can't be created"); } } } string threadName = "DebuggerThread:"; if (activity.Parent != null) { threadName += activity.Parent.DisplayName; } else // Special case for the root of WorklowService that does not have a parent. { threadName += activity.DisplayName; } int newThreadId = this.stateManager.CreateLogicalThread(threadName); Stack<Activity> newStack = new Stack<Activity>(); this.runningThreads.Add(newThreadId, newStack); if (!this.DebugStartedAtRoot && ancestors != null) { // Need to create callstack to current activity. PrimeCallStack(newThreadId, ancestors); } return newThreadId; }
/// <summary> /// if anyone wants to improve this algorithm, feel welcome! </summary> protected internal virtual bool isTreeMatched(ActivityInstance expectedInstance, ActivityInstance actualInstance) { if (!expectedInstance.ActivityId.Equals(actualInstance.ActivityId) || (!string.ReferenceEquals(expectedInstance.Id, null) && !expectedInstance.Id.Equals(actualInstance.Id))) { return(false); } else { if (expectedInstance.ChildActivityInstances.Length != actualInstance.ChildActivityInstances.Length) { return(false); } else { IList <ActivityInstance> unmatchedInstances = new List <ActivityInstance>(Arrays.asList(expectedInstance.ChildActivityInstances)); foreach (ActivityInstance actualChild in actualInstance.ChildActivityInstances) { bool matchFound = false; foreach (ActivityInstance expectedChild in new List <ActivityInstance>(unmatchedInstances)) { if (isTreeMatched(expectedChild, actualChild)) { unmatchedInstances.Remove(actualChild); matchFound = true; break; } } if (!matchFound) { return(false); } } if (expectedInstance.ChildTransitionInstances.Length != actualInstance.ChildTransitionInstances.Length) { return(false); } IList <TransitionInstance> unmatchedTransitionInstances = new List <TransitionInstance>(Arrays.asList(expectedInstance.ChildTransitionInstances)); foreach (TransitionInstance child in actualInstance.ChildTransitionInstances) { IEnumerator <TransitionInstance> expectedTransitionInstanceIt = unmatchedTransitionInstances.GetEnumerator(); bool matchFound = false; while (expectedTransitionInstanceIt.MoveNext() && !matchFound) { TransitionInstance expectedChild = expectedTransitionInstanceIt.Current; if (expectedChild.ActivityId.Equals(child.ActivityId)) { matchFound = true; //JAVA TO C# CONVERTER TODO TASK: .NET enumerators are read-only: expectedTransitionInstanceIt.remove(); } } if (!matchFound) { return(false); } } } return(true); } }
public void Initialize(ActivityInstance activityInstance) { base.Reinitialize(activityInstance); }
public CollapseTemporaryResolutionLocationWorkItem(Location location, ActivityInstance instance) : base(instance) { _location = location; }
public void NotifyUnhandledException(Exception exception, ActivityInstance source) { Fx.Assert(this.activityExecutor != null, "ActivityExecutor null in NotifyUnhandledException."); this.activityExecutor.NotifyUnhandledException(exception, source); }
private void OnExceptionFromCancelHandler(NativeActivityFaultContext context, Exception propagatedException, ActivityInstance propagatedFrom) { this.suppressCancel.Set(context, false); }
private void LoopActionComplete(NativeActivityContext context, ActivityInstance completedInstance) { Execute(context); }
void OnMainActivityComplete(NativeActivityContext context, ActivityInstance completedInstance) { //Pass }
private bool OnActivityInstanceLoaded(ActivityInstance activityInstance, ActivityExecutor executor) { return(activityInstance.TryFixupChildren(this, executor)); }
private void OnFaulted(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom) { //TODO }
public CollapseTemporaryResolutionLocationWorkItem(Location location, ActivityInstance instance) : base(instance) { this.location = location; }
private void OnCompleted(NativeActivityContext context, ActivityInstance completedInstance) { //TODO }
public BookmarkCallbackWrapper(BookmarkCallback callback, ActivityInstance owningInstance) : this(callback, owningInstance, BookmarkOptions.None) { }
internal ActivityInstanceReference(ActivityInstance activity) { _activityInstance = activity; }
internal ActivityStateRecord(Guid instanceId, ActivityInstance instance, ActivityInstanceState state) : this(instanceId, new ActivityInfo(instance), state) { }
public FuncCompletionCallbackWrapper(CompletionCallback <T> callback, ActivityInstance owningInstance) : base(callback, owningInstance) { this.NeedsToGatherOutputs = true; }
public void OnEnterState(ActivityInstance instance) { Fx.Assert(instance != null, "ActivityInstance cannot be null"); Activity activity = instance.Activity; if (this.EnsureInstrumented(activity)) { this.EnterState(GetOrCreateThreadId(activity, instance), activity, GenerateLocals(instance)); } }
private void onComplete(NativeActivityContext context, ActivityInstance completedInstance) { Console.WriteLine("ClickActivity onComplete"); }
public void OnLeaveState(ActivityInstance activityInstance) { Fx.Assert(activityInstance != null, "ActivityInstance cannot be null"); if (this.EnsureInstrumented(activityInstance.Activity)) { this.LeaveState(activityInstance.Activity); } }
public EmptyWithCancelationCheckWorkItem(ActivityInstance activityInstance, ActivityInstance completedInstance) : base(activityInstance) { this.completedInstance = completedInstance; this.IsEmpty = true; }
// Get threads currently executing the parent of the given activity, // if none then create a new one and prep the call stack to current state. int GetOrCreateThreadId(Activity activity, ActivityInstance instance) { int threadId = -1; if (activity.Parent != null && !IsParallelActivity(activity.Parent)) { threadId = GetExecutingThreadId(activity.Parent, false); } if (threadId < 0) { threadId = CreateLogicalThread(activity, instance, false); } return threadId; }
public CompleteAsyncCodeActivityWorkItem(AsyncOperationContext asyncContext, ActivityInstance instance, IAsyncResult result) : base(instance) { _result = result; _asyncContext = asyncContext; this.ExitNoPersistRequired = true; }
protected override void Track(TrackingRecord trackRecord, TimeSpan timeStamp) { try { string State = "unknown"; Guid InstanceId = trackRecord.InstanceId; ActivityStateRecord activityStateRecord = trackRecord as ActivityStateRecord; ActivityScheduledRecord activityScheduledRecord = trackRecord as ActivityScheduledRecord; WorkflowInstanceRecord workflowInstanceRecord = trackRecord as WorkflowInstanceRecord; if (workflowInstanceRecord != null) { if (workflowInstanceRecord.State == WorkflowInstanceStates.Started || workflowInstanceRecord.State == WorkflowInstanceStates.Resumed) { lock (timerslock) timers.Add(InstanceId.ToString(), new Dictionary <string, Stopwatch>()); } if (workflowInstanceRecord.State == WorkflowInstanceStates.Aborted || workflowInstanceRecord.State == WorkflowInstanceStates.Canceled || workflowInstanceRecord.State == WorkflowInstanceStates.Completed || workflowInstanceRecord.State == WorkflowInstanceStates.Deleted || workflowInstanceRecord.State == WorkflowInstanceStates.Suspended || workflowInstanceRecord.State == WorkflowInstanceStates.Terminated || workflowInstanceRecord.State == WorkflowInstanceStates.UnhandledException || workflowInstanceRecord.State == WorkflowInstanceStates.UpdateFailed) { if (timers.ContainsKey(InstanceId.ToString())) { lock (timerslock) timers.Remove(InstanceId.ToString()); } } } //if (activityStateRecord != null || activityScheduledRecord != null) if (activityStateRecord != null) { string ActivityId = null; var Instance = WorkflowInstance.Instances.Where(x => x.InstanceId == InstanceId.ToString()).FirstOrDefault(); if (activityStateRecord.Activity != null && !string.IsNullOrEmpty(activityStateRecord.Activity.Id)) { ActivityId = activityStateRecord.Activity.Id; } // var sw = new Stopwatch(); sw.Start(); if (timers.ContainsKey(InstanceId.ToString()) && !string.IsNullOrEmpty(ActivityId)) { var timer = timers[InstanceId.ToString()]; if (activityStateRecord.State == ActivityStates.Executing) { if (!timer.ContainsKey(ActivityId)) { Stopwatch sw = new Stopwatch(); sw.Start(); timer.Add(ActivityId, sw); } } if (activityStateRecord.State != ActivityStates.Executing) { if (timer.ContainsKey(ActivityId)) { Stopwatch sw = timer[ActivityId]; if (sw.ElapsedMilliseconds > 0) { var TypeName = activityStateRecord.Activity.TypeName; if (TypeName.IndexOf("`") > -1) { TypeName = TypeName.Substring(0, TypeName.IndexOf("`")); } RobotInstance.activity_duration.WithLabels((activityStateRecord.Activity.Name, TypeName, Instance.Workflow.name)).Observe(sw.ElapsedMilliseconds / 1000); } } } } if (activityStateRecord.Activity != null && !string.IsNullOrEmpty(activityStateRecord.Activity.Name) && Instance != null && Instance.Workflow != null) { var TypeName = activityStateRecord.Activity.TypeName; if (TypeName.IndexOf("`") > -1) { TypeName = TypeName.Substring(0, TypeName.IndexOf("`")); } RobotInstance.activity_counter.WithLabels((activityStateRecord.Activity.Name, TypeName, Instance.Workflow.name)).Inc(); } foreach (var v in activityStateRecord.Variables) { if (Instance.Variables.ContainsKey(v.Key)) { Instance.Variables[v.Key].value = v.Value; } else { if (v.Value != null) { Instance.Variables.Add(v.Key, new WorkflowInstanceValueType(v.Value.GetType(), v.Value)); } } //wfi.variables.Add(v.Key, v.Value); } // Log.Activity(activityStateRecord.State + " " + activityStateRecord.Activity.Id + " " + activityStateRecord.Activity.Name); } if (activityScheduledRecord != null) { var Instance = WorkflowInstance.Instances.Where(x => x.InstanceId == InstanceId.ToString()).FirstOrDefault(); if (Instance == null || Instance.wfApp == null) { return; } var wfApp = Instance.wfApp; var executor = typeof(System.Activities.Hosting.WorkflowInstance).GetField("executor", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(wfApp); var scheduler = executor.GetType().GetField("scheduler", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(executor); string ActivityId = null; string ChildActivityId = null; if (activityStateRecord != null) { ActivityId = activityStateRecord.Activity.Id; State = activityStateRecord.State.ToLower(); } if (activityScheduledRecord != null) { State = "Scheduled"; if (activityScheduledRecord.Activity != null) { ActivityId = activityScheduledRecord.Activity.Id; } if (activityScheduledRecord.Child != null) { ChildActivityId = activityScheduledRecord.Child.Id; } } if (activityScheduledRecord.Activity == null && activityScheduledRecord.Child != null) { // this will make "1" be handles twice, but "1" is always sendt AFTER being scheduled, but we can catch it here ? ActivityId = activityScheduledRecord.Child.Id; ChildActivityId = activityScheduledRecord.Child.Id; } if (string.IsNullOrEmpty(ActivityId)) { return; } if (activityScheduledRecord.Child.Id == "1.11") { // scheduler.GetType().GetMethod("ClearAllWorkItems", BindingFlags.Public | BindingFlags.Instance).Invoke(scheduler, new object[] { executor }); // scheduler.GetType().GetMethod("ScheduleWork", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(scheduler, new object[] { false }); //var firstWorkItem = scheduler.GetType().GetField("firstWorkItem", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(scheduler); //firstWorkItem.GetType().GetMethod("Release", BindingFlags.Public | BindingFlags.Instance).Invoke(firstWorkItem, new object[] { executor }); //firstWorkItem.GetType().GetMethod("Dispose", BindingFlags.Public | BindingFlags.Instance).Invoke(firstWorkItem, new object[] { executor }); //scheduler.GetType().GetMethod("NotifyWorkCompletion", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(scheduler, new object[] { }); } if (activityScheduledRecord.Activity != null) { // Log.Activity("Scheduled " + activityScheduledRecord.Activity.Id + " " + activityScheduledRecord.Activity.Name + " -> " + activityScheduledRecord.Child.Id + " " + activityScheduledRecord.Child.Name); } else if (activityScheduledRecord.Child != null) { // Log.Activity("Scheduled " + activityScheduledRecord.Child.Id + " " + activityScheduledRecord.Child.Name); } if (Instance.Variables == null) { Instance.Variables = new Dictionary <string, WorkflowInstanceValueType>(); } if (activityStateRecord != null) { foreach (var v in Instance.Variables.ToList()) { if (!activityStateRecord.Variables.ContainsKey(v.Key)) { Instance.Variables.Remove(v.Key); } } foreach (var v in activityStateRecord.Variables) { if (Instance.Variables.ContainsKey(v.Key)) { Instance.Variables[v.Key].value = v.Value; } } } var instanceMapField = executor.GetType().GetField("instanceMap", BindingFlags.NonPublic | BindingFlags.Instance); // get SerializedProgramMapping to have InstanceMap get filled, needed by SerializedProgramMapping var SerializedProgramMapping = executor.GetType().GetProperty("SerializedProgramMapping", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(executor); ActivityInstance activityInstance = executor.GetType().GetField("rootInstance", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(executor) as ActivityInstance; // Sometimes we can find the ActivityInstance in rootInstance ActivityInstance result = findActivityInstance(executor, activityInstance, ActivityId); // But more often, we find it in InstanceMapping var instanceMap = instanceMapField.GetValue(executor); if (instanceMap != null && result == null) { var _list = SerializedProgramMapping.GetType().GetProperty("InstanceMapping", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(SerializedProgramMapping); foreach (System.Collections.DictionaryEntry kvp in (System.Collections.IDictionary)_list) { var a = kvp.Key as Activity; if (a == null) { continue; } if (result == null && a.Id == ActivityId) { result = findActivityInstance(kvp.Value, ActivityId); } } } if (result != null) { WorkflowDataContext context = null; var cs = typeof(WorkflowDataContext).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance); ConstructorInfo c = cs.First(); try { object o = c.Invoke(new Object[] { executor, result, true }); context = o as WorkflowDataContext; var vars = context.GetProperties(); foreach (dynamic v in vars) { var value = v.GetValue(context); if (Instance.Variables.ContainsKey(v.DisplayName)) { Instance.Variables[v.DisplayName] = new WorkflowInstanceValueType(v.PropertyType, value); } else { Instance.Variables.Add(v.DisplayName, new WorkflowInstanceValueType(v.PropertyType, value)); } } } catch (Exception ex) { Log.Debug(ex.Message); } } OnVisualTracking?.Invoke(Instance, ActivityId, ChildActivityId, State); } else { // Log.Debug(trackRecord.ToString()); } } catch (Exception ex) { Log.Error(ex.ToString()); } }
private void onComplete(NativeActivityContext context, ActivityInstance completedInstance) { }