private static List <Tuple <XElement, XElement> > CreateNodeLabels(Dictionary <JoinableTask, XElement> tasksAndElements)
        {
            Requires.NotNull(tasksAndElements, nameof(tasksAndElements));

            var result = new List <Tuple <XElement, XElement> >();

            foreach (KeyValuePair <JoinableTask, XElement> tasksAndElement in tasksAndElements)
            {
                JoinableTask?pendingTask = tasksAndElement.Key;
                XElement?    node        = tasksAndElement.Value;
                int          queueIndex  = 0;
                foreach (JoinableTaskFactory.SingleExecuteProtector?pendingTasksElement in pendingTask.MainThreadQueueContents)
                {
                    queueIndex++;
                    XElement?callstackNode = Dgml.Node(node.Attribute("Id").Value + "MTQueue#" + queueIndex, GetAsyncReturnStack(pendingTasksElement));
                    XElement?callstackLink = Dgml.Link(callstackNode, node);
                    result.Add(Tuple.Create(callstackNode, callstackLink));
                }

                foreach (JoinableTaskFactory.SingleExecuteProtector?pendingTasksElement in pendingTask.ThreadPoolQueueContents)
                {
                    queueIndex++;
                    XElement?callstackNode = Dgml.Node(node.Attribute("Id").Value + "TPQueue#" + queueIndex, GetAsyncReturnStack(pendingTasksElement));
                    XElement?callstackLink = Dgml.Link(callstackNode, node);
                    result.Add(Tuple.Create(callstackNode, callstackLink));
                }
            }

            return(result);
        }
Example #2
0
        private static XElement CreateAwaiterNode(Awaiter awaiter)
        {
            Requires.NotNull(awaiter, nameof(awaiter));

            var label = new StringBuilder();

            label.AppendLine(awaiter.Kind.ToString());
            if (awaiter.Options != LockFlags.None)
            {
                label.AppendLine("Options: " + awaiter.Options);
            }

            Delegate lockWaitingContinuation;

#if DESKTOP
            if (awaiter.RequestingStackTrace != null)
            {
                label.AppendLine(awaiter.RequestingStackTrace.ToString());
            }
#endif

            if ((lockWaitingContinuation = awaiter.LockRequestingContinuation) != null)
            {
                try
                {
                    foreach (var frame in lockWaitingContinuation.GetAsyncReturnStackFrames())
                    {
                        label.AppendLine(frame);
                    }
                }
                catch (Exception ex)
                {
                    // Just eat the exception so we don't crash during a hang report.
                    Report.Fail("GetAsyncReturnStackFrames threw exception: ", ex);
                }
            }

            if (label.Length >= Environment.NewLine.Length)
            {
                label.Length -= Environment.NewLine.Length;
            }

            XElement element = Dgml.Node(GetAwaiterId(awaiter), label.ToString());
            return(element);
        }
        private static Dictionary <JoinableTaskCollection, XElement> CreateNodesForJoinableTaskCollections(IEnumerable <JoinableTask> tasks)
        {
            Requires.NotNull(tasks, nameof(tasks));

            var collectionsSet = new HashSet <JoinableTaskCollection>(tasks.SelectMany(t => t.ContainingCollections));
            var result         = new Dictionary <JoinableTaskCollection, XElement>(collectionsSet.Count);
            int collectionId   = 0;

            foreach (JoinableTaskCollection?collection in collectionsSet)
            {
                collectionId++;
                var      label   = string.IsNullOrEmpty(collection.DisplayName) ? "Collection #" + collectionId : collection.DisplayName;
                XElement?element = Dgml.Node("Collection#" + collectionId, label, group: "Expanded")
                                   .WithCategories("Collection");
                result.Add(collection, element);
            }

            return(result);
        }
        private Dictionary <JoinableTask, XElement> CreateNodesForPendingTasks()
        {
            var pendingTasksElements = new Dictionary <JoinableTask, XElement>();

            lock (this.pendingTasks)
            {
                int taskId = 0;
                foreach (JoinableTask?pendingTask in this.pendingTasks)
                {
                    taskId++;

                    string methodName = string.Empty;
                    System.Reflection.MethodInfo?entryMethodInfo = pendingTask.EntryMethodInfo;
                    if (entryMethodInfo is object)
                    {
                        methodName = string.Format(
                            CultureInfo.InvariantCulture,
                            " ({0}.{1})",
                            entryMethodInfo.DeclaringType?.FullName,
                            entryMethodInfo.Name);
                    }

                    XElement?node = Dgml.Node("Task#" + taskId, "Task #" + taskId + methodName)
                                    .WithCategories("Task");
                    if (pendingTask.HasNonEmptyQueue)
                    {
                        node.WithCategories("NonEmptyQueue");
                    }

                    if (pendingTask.State.HasFlag(JoinableTask.JoinableTaskFlags.SynchronouslyBlockingMainThread))
                    {
                        node.WithCategories("MainThreadBlocking");
                    }

                    pendingTasksElements.Add(pendingTask, node);
                }
            }

            return(pendingTasksElements);
        }