示例#1
0
        /// <summary>
        /// This method removes all of the non-acitivity traces, and then orders the activity traces so they will match
        ///  more closely the expected traces. This is required for complex parallel traces.
        /// </summary>
        public void OrderTraces()
        {
            List <ActivityTrace> traceSteps = new List <ActivityTrace>();
            List <UserTrace>     userTraces = new List <UserTrace>();

            // Find the starting node
            lock (this.Steps)
            {
                foreach (IActualTraceStep ts in this.Steps)
                {
                    if (ts is ActivityTrace)
                    {
                        traceSteps.Add(ts as ActivityTrace);
                    }
                    else if (ts is UserTrace)
                    {
                        userTraces.Add(ts as UserTrace);
                    }
                    else
                    {
                        //Log.TraceInternal("[ActualTrace]ParallelValidation removing trace " + ts.ToString());
                    }
                }
            }

            Dictionary <string, ATNode> sortedSteps = new Dictionary <string, ATNode>();
            ATNode rootNode = null;

            this.Steps.Clear();

            // do this until we have completely constructed the tree, in case traces get written out in
            //  an order we arent expecting, loop until either we cant make any more changes, or until
            //  all the traces have been ordered.
            bool changed;

            while (traceSteps.Count > 0)
            {
                changed = false;
                for (int x = 0; x < traceSteps.Count; x++)
                {
                    ActivityTrace at = traceSteps[x];
                    ATNode        parentnode;

                    // If a new activity was scheduled
                    if (at.IsScheduled)
                    {
                        // When activityID is null, this is the root activity.
                        if (at.ActivityId == null)
                        {
                            rootNode = new ATNode()
                            {
                                trace = at,
                            };

                            // add root node to the tree using its' activity id and instanceid (for when activities get
                            //  instantiated multiple times, like with parallelforeach
                            sortedSteps[1 + ":" + 1] = rootNode;
                            traceSteps.RemoveAt(x--);
                            changed = true;
                        }
                        // otherwise, if parent has already been found, add this node
                        else if (sortedSteps.TryGetValue(at.ActivityId + ":" + at.ActivityInstanceId, out parentnode))
                        {
                            ATNode newnode = new ATNode()
                            {
                                trace  = at,
                                parent = parentnode
                            };
                            // add the node to its parent.
                            sortedSteps[at.ChildActivityId + ":" + at.ChildActivityInstanceId] = newnode;
                            parentnode.children.Add(newnode);
                            traceSteps.RemoveAt(x--);
                            changed = true;
                        }
                    }
                    else
                    {
                        if (sortedSteps.TryGetValue(at.ActivityId + ":" + at.ActivityInstanceId, out parentnode))
                        {
                            ATNode node = new ATNode()
                            {
                                trace  = at,
                                parent = parentnode.parent
                            };

                            // if root node, just add as the last child, if it ends up being out of order the
                            //  validation logic will correct it.
                            if (parentnode.parent == null)
                            {
                                parentnode.children.Add(node);
                            }
                            else
                            {
                                // otherwise just setup parent
                                parentnode.parent.children.Add(node);
                            }
                            traceSteps.RemoveAt(x--);
                            changed = true;
                        }
                    }
                }

                if (rootNode == null)
                {
                    // there is no root node, we cant construct without it
                    //Log.TraceInternal("[ActualTrace]Parallel tracing couldnt find a root node, using the unordered traces.");
                    return;
                }

                if (!changed)
                {
                    // the tree is in a state that we cant reconstruct
                    //Log.TraceInternal("[ActualTrace]Parallel tracing couldnt find the parent for a node, using the unordered traces");
                    return;
                }
            }

            foreach (UserTrace ut in userTraces)
            {
                (sortedSteps[ut.ActivityParent]).userTraces.Add(ut);
            }

            lock (this.Steps)
            {
                this.Steps.AddRange(rootNode.GetTraces());
            }
        }