Ottieni un elenco di discussioni

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 } 

Metodo 1: Ottieni thread OS

Questo ottiene l’elenco dei thread del sistema operativo:

 ProcessThreadCollection currentThreads = Process.GetCurrentProcess().Threads; foreach (ProcessThread thread in currentThreads) { } 

Metodo 2: ottenere thread gestiti

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.

Metodo 2.1: codice più semplice per ottenere thread gestiti

  1. Dai un’occhiata a Microsoft.Diagnostics.Runtime su GitHub .
  2. Installa il pacchetto NuGet CLR Memory Diagnostics (ClrMD) .

È 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) { } } 

Metodo 2.2: esempio di come cercare nei thread gestiti dallo stack trace

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 .

analisi

Testato con tutte le combinazioni di:

  • Visual Studio 2015 SP1
  • .NET 4.5
  • .NET 4.6.0
  • .NET 4.6.1
  • C # 5.0
  • C # 6.0

Riferimenti

Vedi ClrMd genera un’eccezione durante la creazione del runtime .