private void DumpRunningThreadpoolThreads(ClrMDHelper helper) { Dictionary <string, ThreadDistributionItem> distribution = new Dictionary <string, ThreadDistributionItem>(8 * 1024); StringBuilder sb = new StringBuilder(8 * 1024 * 1024); _host.WriteLine("\r\n ID ThreadOBJ Locks Details"); _host.WriteLine("-----------------------------------------------------------------------------------"); foreach (var thread in _host.Session.Clr.Threads .Where(t => t.IsThreadpoolWorker) .OrderBy(t => (t.LockCount > 0) ? -1 : (!t.IsAlive ? t.ManagedThreadId + 10000 : t.ManagedThreadId))) { string details = GetCallStackInfo(helper, thread); sb.AppendFormat("{0,4} {1} {2} {3}\r\n", thread.ManagedThreadId.ToString(), thread.Address.ToString("X16"), ((thread.LockCount > 0) ? thread.LockCount.ToString("D4") : " "), details ); // the details might have different forms // 155 000000CC08EF5030 Thread // + [method signature] // => WaitHandle.WaitOneNative(0x000000CFC388EBA0 : SafeWaitHandle) // 156 000000CC08EFD050 Task | [method signature] // + [method signature] // => WaitHandle.WaitOneNative(0x000000CF40B7F480 : SafeWaitHandle) // but we just want to group by the first TWO lines (not the "=> ..." that contains pointers values that will break the grouping // so the key is computed up to "=>" string key = details; int pos = details.IndexOf("=>"); if (pos == -1) { key = string.Intern(details); } else { int lastLineMarkerPos = details.IndexOf("\r\n"); if (lastLineMarkerPos == -1) { Debug.Fail("unexpected item format" + details); lastLineMarkerPos = pos; } key = string.Intern(details.Substring(0, lastLineMarkerPos + "\r\n".Length)); } ThreadDistributionItem state; if (distribution.ContainsKey(key)) { state = distribution[key]; } else { state = new ThreadDistributionItem() { Key = key, Count = 0 }; distribution[key] = state; } state.Count++; } _host.WriteLine(sb.ToString()); // build a summary if (distribution.Values.Count > 0) { sb.Clear(); sb.AppendLine("\r\n____________________________________________________________________________________________________\r\nCount Details\r\n----------------------------------------------------------------------------------------------------"); int total = 0; foreach (var item in distribution.Values.OrderBy(t => t.Count)) { sb.AppendLine(string.Format(" {0,4} {1}", item.Count.ToString(), item.Key)); total += item.Count; } sb.AppendLine(" ----"); sb.AppendLine(string.Format(" {0,4}\r\n", total.ToString())); _host.WriteLine(sb.ToString()); } }
private static void DumpRunningThreadpoolThreads(ClrMDHelper helper) { Dictionary <string, ThreadDistributionItem> distribution = new Dictionary <string, ThreadDistributionItem>(8 * 1024); Console.WriteLine("\r\n ID ThreadOBJ Locks Details"); Console.WriteLine("-----------------------------------------------------------------------------------"); foreach (var thread in Runtime.Threads.Where(t => t.IsThreadpoolWorker).OrderBy(t => (t.LockCount > 0) ? -1 : (!t.IsAlive ? t.ManagedThreadId + 10000 : t.ManagedThreadId))) { string details = string.Intern(GetCallStackInfo(helper, thread)); if (thread.IsAlive) { Console.WriteLine(string.Format( "{0,4} <link cmd=\"~~[{1}]e!ClrStack\">{2}</link> {3} {4}", thread.ManagedThreadId.ToString(), thread.OSThreadId.ToString("X"), thread.Address.ToString("X16"), ((thread.LockCount > 0) ? thread.LockCount.ToString("D4") : " "), details )); } else { Console.WriteLine(string.Format( "{0,4} {1} {2} {3}", thread.ManagedThreadId.ToString(), thread.Address.ToString("X16"), ((thread.LockCount > 0) ? thread.LockCount.ToString("D4") : " "), details )); } ThreadDistributionItem state; if (distribution.ContainsKey(details)) { state = distribution[details]; } else { state = new ThreadDistributionItem() { Key = details, Count = 0 }; distribution[details] = state; } state.Count++; } // build a summary if (distribution.Values.Count > 0) { Console.WriteLine("\r\n____________________________________________________________________________________________________\r\nCount Details\r\n----------------------------------------------------------------------------------------------------"); int total = 0; foreach (var item in distribution.Values.OrderBy(t => t.Count)) { Console.WriteLine(string.Format(" {0,4} {1}", item.Count.ToString(), item.Key)); total += item.Count; } Console.WriteLine(" ----"); Console.WriteLine(string.Format(" {0,4}\r\n", total.ToString())); } }