2010-01-25 9 views
12

Manchmal durchläuft ich eine Anwendung im Debug-Modus, bis ich auf einer bestimmten Zeile "Schritt" drücke und es viel zu lange dauert, etwas zu tun, 100% CPU verbrauchen. Zu diesem Zeitpunkt habe ich den "Break" -Button gedrückt und versuche herauszufinden, was gerade läuft.Alter, wo ist mein Thread ?? (oder: benenne einen .NET-Thread-Pool-Thread um - ist das möglich?)

Das Problem ist, diese App hat eine stattliche Menge von Threads ausgeführt, und zu der Zeit, wenn ich 'Break', der Ausführungspunkt geht an den GUI-Thread, der wahrscheinlich nur ein "Warten" tun. Ich muss dann durch die vorhandenen Threads jagen (ich zählte sie - diesmal sind es 37!) Und versuchte den zu finden, auf dem ich gerade lief. Ich musste auf den Stapel von jedem von ihnen schauen, bis ich den finde, den ich suchte.

Der Thread, auf dem ich ausgeführt werde, ist ein async-Aufruf, also wird er auf einem Thread-Pool-Thread ausgeführt. Ich möchte diesem Thread einen beschreibenden Namen geben und seinen Namen am Ende des Vorgangs zurücksetzen.

Das Problem ist, das Eigentum kann nur einmal eingestellt wird, danach es ein InvalidOperationException gibt.

Irgendwelche Vorschläge?

Oh ja, ich laufe VS2005/.NET 2.0 aber ich bin auch neugierig, wenn neuere Versionen bessere Möglichkeiten haben, damit umzugehen.

+0

Upvote nur für Ihren Titel! (nicht wirklich, tolle Frage) –

Antwort

4

Definieren Sie Ihre eigenen Threadstatic Eigenschaft

public class ThreadMarker:IDisposable 
{ 
    [ThreadStatic] 
    private static string __Name; 

    static Dictionary<int,string> ThreadNames=new Dictionary<int,string>(); 

    public static Name{get{return __Name;}} 

    public ThreadMarker(string name) 
    { 
    lock(ThreadNames){ 
     ThreadNames[Thread.CurrentThread.ManagedThreadId]=name; 
    } 
    __Name=name; 
    } 

    public void Dispose() 
    { 
    ThreadNames.Remove(Thread.CurrentThread.ManagedThreadId); 
    __Name="Unowned"; 
    } 
} 

Sie können sogar Ihre eigenen Wrapper schreiben, die Ihre Aktion/Delegierten/Asynchron-Rückruf in dieser Anweisung using automagically wickelt.

class NamedHandler<TArg>{ 
    public readonly Action<TArg> Handler; 

    NamedHandler(string name,Action<TArg> handler){ 

    Handler=arg=>{ 
     using(new ThreadMarker(name)){ 
     handler(arg); 
     } 
    }  
    } 
} 

// usage 
void doStuff(string arg){ 
    Log("Stuf done in thread {0} ",ThreadMarker.Name); 
}  

ThreadPool.QueueUserWorkItem(new NamedHandler<string>("my Thread",arg=>DoStuff(arg)).Handler); 

Dann, wenn Sie den Debugger zu stoppen, haben einen Blick auf den Inhalt der Variable ThreadMarker.ThreadNames und Sie werden sehen, welche verwaltete Threads in Ihrem Namen Handler stecken.

+0

Wie hilft das bei der Identifizierung des Threads im Debugger? Wird es stattdessen diese Eigenschaft tatsächlich aufnehmen? Das interne Feld für den Namen ist "m_Name" nicht "__Name" und es ist nicht Thread statisch. –

+0

Ich habe einen Code für Ihr Problem hinzugefügt. Sie können einen Thread nicht umbenennen, sobald er ausgeführt wird. Sie können jedoch ein threadstatisches Markerfeld verwenden, das Sie beim Einfrieren Ihrer App überprüfen können, um festzustellen, welcher Thread welche Ihrer Handler ausführt. –