2010-01-25 21 views
12

A volte mi trovo a passare da un'applicazione in modalità Debug, fino a quando non faccio "step" su una determinata riga e ci vuole troppo tempo a fare qualcosa, mangiare fino al 100% della CPU. A questo punto, premo il pulsante "Interrompi" e provo a scoprire che cosa sta facendo funzionare così a lungo.Amico, dov'è il mio thread ?? (o: rinominare un thread pool di thread .NET - è possibile?)

Il problema è che questa app ha una notevole quantità di thread in esecuzione e al momento in cui si preme "Break", il punto di esecuzione va al thread della GUI che probabilmente sta solo facendo "Wait". Devo quindi dare la caccia ai thread esistenti (li ho contati - questa volta hanno 37!) Cercando di trovare quello su cui stavo eseguendo. Dovrei guardare la pila di ognuno di essi finché non trovo quello che stavo cercando.

Il thread su cui sto lavorando è un richiamo asincrono, quindi viene eseguito su un thread del thread. Mi piacerebbe dare a questo thread un nome descrittivo e resettare il suo nome alla fine dell'operazione.

Il problema è, di proprietà può essere impostato solo una volta , poi dà un InvalidOperationException.

Qualche suggerimento?

Oh sì, sto eseguendo VS2005/.NET 2.0 ma sono anche curioso di sapere se le versioni più recenti hanno modi migliori per gestire questo.

+0

Upvote solo per il tuo titolo! (non proprio, ottima domanda) –

risposta

4

Definire la vostra proprietà ThreadStatic

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"; 
    } 
} 

Si può anche scrivere il proprio involucro che avvolge automagicamente il callback azione/delegato/async in questa istruzione using.

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); 

Poi, quando si arresta il debugger, uno sguardo ai contenuti delle ThreadMarker.ThreadNames variabili e vedrete che gestite le discussioni sono bloccati nei gestori di nome.

+0

In che modo questo aiuterà a identificare il thread all'interno del debugger? In realtà raccoglierà invece questa proprietà? Il campo interno utilizzato per il nome è "m_Name" non "__Name" e non è thread statico. –

+0

Ho aggiunto del codice per il tuo problema. Non sarà possibile rinominare una discussione una volta che è in esecuzione. Tuttavia, ciò che puoi fare è utilizzare un campo indicatore di threadstatic che puoi controllare quando blocchi l'app per vedere quale thread sta eseguendo quale dei tuoi gestori. –

Problemi correlati