concurrentbag - concurrentdictionary c# example
¿Obtiene la lista de hilos gestionados actualmente activos en.NET? (2)
¿Es factible que almacene información de subprocesos en una búsqueda a medida que crea cada subproceso en su aplicación?
A medida que se inicia cada subproceso, puede obtener su ID usando AppDomain.GetCurrentThreadId()
. Más tarde, puede usar esto para realizar una referencia cruzada con los datos devueltos por Process.Threads
.
Para un tipo de función de "registro de información para soporte", me gustaría enumerar y volcar la información del hilo activo.
Soy muy consciente del hecho de que las condiciones de carrera pueden hacer que esta información sea poco precisa, pero me gustaría tratar de obtener el mejor resultado posible, incluso si no es 100% exacto.
Miré Process.Threads, pero devuelve los objetos ProcessThread, me gustaría tener una colección de objetos Thread, para poder registrar su nombre, y si son hilos de fondo o no.
¿Hay tal colección disponible, incluso si solo es una instantánea de los hilos activos cuando la llamo?
es decir.
Thread[] activeThreads = ??
Tenga en cuenta, para ser claro, no estoy preguntando sobre Process.Threads, esta colección me da mucho, pero no todo lo que quiero. Quiero saber cuánto tiempo están usando los hilos específicos específicos en nuestra aplicación (lo que significa que tendré que buscar conectar los dos tipos de objetos más adelante, pero los nombres son más importantes que el tiempo de CPU para empezar).
Si está dispuesto a reemplazar las creaciones de Thread
su aplicación con otra clase contenedora, dicha clase contenedora puede rastrear los Thread
activo e inactivo por usted. Aquí hay un shell mínimo útil de tal envoltorio:
namespace ThreadTracker
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
public class TrackedThread
{
private static readonly IList<Thread> threadList = new List<Thread>();
private readonly Thread thread;
private readonly ParameterizedThreadStart start1;
private readonly ThreadStart start2;
public TrackedThread(ParameterizedThreadStart start)
{
this.start1 = start;
this.thread = new Thread(this.StartThreadParameterized);
lock (threadList)
{
threadList.Add(this.thread);
}
}
public TrackedThread(ThreadStart start)
{
this.start2 = start;
this.thread = new Thread(this.StartThread);
lock (threadList)
{
threadList.Add(this.thread);
}
}
public TrackedThread(ParameterizedThreadStart start, int maxStackSize)
{
this.start1 = start;
this.thread = new Thread(this.StartThreadParameterized, maxStackSize);
lock (threadList)
{
threadList.Add(this.thread);
}
}
public TrackedThread(ThreadStart start, int maxStackSize)
{
this.start2 = start;
this.thread = new Thread(this.StartThread, maxStackSize);
lock (threadList)
{
threadList.Add(this.thread);
}
}
public static int Count
{
get
{
lock (threadList)
{
return threadList.Count;
}
}
}
public static IEnumerable<Thread> ThreadList
{
get
{
lock (threadList)
{
return new ReadOnlyCollection<Thread>(threadList);
}
}
}
// either: (a) expose the thread object itself via a property or,
// (b) expose the other Thread public methods you need to replicate.
// This example uses (a).
public Thread Thread
{
get
{
return this.thread;
}
}
private void StartThreadParameterized(object obj)
{
try
{
this.start1(obj);
}
finally
{
lock (threadList)
{
threadList.Remove(this.thread);
}
}
}
private void StartThread()
{
try
{
this.start2();
}
finally
{
lock (threadList)
{
threadList.Remove(this.thread);
}
}
}
}
}
y un controlador de prueba rápido de la misma (tenga en cuenta que no iterar sobre la lista de hilos, simplemente obtener el recuento en la lista):
namespace ThreadTracker
{
using System;
using System.Threading;
internal static class Program
{
private static void Main()
{
var thread1 = new TrackedThread(DoNothingForFiveSeconds);
var thread2 = new TrackedThread(DoNothingForTenSeconds);
var thread3 = new TrackedThread(DoNothingForSomeTime);
thread1.Thread.Start();
thread2.Thread.Start();
thread3.Thread.Start(15);
while (TrackedThread.Count > 0)
{
Console.WriteLine(TrackedThread.Count);
}
Console.ReadLine();
}
private static void DoNothingForFiveSeconds()
{
Thread.Sleep(5000);
}
private static void DoNothingForTenSeconds()
{
Thread.Sleep(10000);
}
private static void DoNothingForSomeTime(object seconds)
{
Thread.Sleep(1000 * (int)seconds);
}
}
}
No estoy seguro de si puede tomar esa ruta, pero logrará el objetivo si puede incorporarse en una etapa temprana de desarrollo.