Voglio elencare tutti i thread in esecuzione ma non utilizzando la class List
. Voglio osservare dynamicmente i thread in esecuzione. Come lo posso fare?
using System.Diagnostics; ProcessThreadCollection currentThreads = Process.GetCurrentProcess().Threads; foreach (ProcessThread thread in currentThreads) { // Do whatever you need }
Questo ottiene l’elenco dei thread del sistema operativo:
ProcessThreadCollection currentThreads = Process.GetCurrentProcess().Threads; foreach (ProcessThread thread in currentThreads) { }
I thread gestiti si trovano in cima ai thread del sistema operativo. Gli ID sono diversi e, in teoria, più di un thread gestito può essere posizionato su un singolo thread del sistema operativo (sebbene in realtà non lo abbia osservato).
Si scopre che ottenere thread gestiti è più difficile di quanto dovrebbe essere.
È quindi ansible utilizzare il pacchetto NuGet per collegarlo al proprio processo e leggere i thread gestiti:
using Microsoft.Diagnostics.Runtime; using (DataTarget target = DataTarget.AttachToProcess( Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive)) { ClrRuntime runtime = target.ClrVersions.First().CreateRuntime(); foreach (ClrThread thread in runtime.Threads) { } }
Sfortunatamente, non sono riuscito a trovare alcun modo per cercare l’elenco di thread in base al nome del thread.
Tuttavia, non tutto è perduto: ecco un esempio di come creare un thread gestito, quindi trovarlo cercando tra i frame dello stack per una corrispondenza nello spazio dei nomi, quindi stampare le sue proprietà:
namespace MyTest { int managedThreadId = 0; var task = Task.Run( () => { // Unfortunately, cant see "Testing" anywhere in result returned // from NuGet package ClrMD ... Thread.CurrentThread.Name = "Testing"; Thread.Sleep(TimeSpan.FromDays(1)); }); // ... so we look for our thread by the first word in this namespace. string startOfThisNamespace = this.GetType().Namespace.ToString().Split('.')[0]; // Is "MyTest". using (DataTarget target = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive)) { ClrRuntime runtime = target.ClrVersions.First().CreateRuntime(); foreach (ClrThread thread in runtime.Threads) { IList stackFrames = thread.StackTrace; List stackframesRelatedToUs = stackFrames .Where(o => o.Method != null && o.Method.ToString().StartsWith(startOfThisNamespace)).ToList(); if (stackframesRelatedToUs.Count > 0) { Console.Write("ManagedThreadId: {0}, OSThreadId: {1}, Thread: IsAlive: {2}, IsBackground: {3}:\n", thread.ManagedThreadId, thread.OSThreadId, thread.IsAlive, thread.IsBackground); Console.Write("- Stack frames related namespace '{0}':\n", startOfThisNamespace); foreach (var s in stackframesRelatedToUs) { Console.Write(" - StackFrame: {0}\n", s.Method.ToString()); } } } } }
È inoltre ansible trovare la corrispondenza corretta salvando ManagedThreadId
all’interno del thread che si crea, quindi cercando lo stesso ID in runtime.Threads
.
Testato con tutte le combinazioni di:
Vedi ClrMd genera un’eccezione durante la creazione del runtime .