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); }
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); }