2010-01-25 12 views
12

Czasami przechodzę przez aplikację w trybie debugowania, dopóki nie wykonam "kroku" w konkretnej linii i zajmuje to zbyt dużo czasu, aby coś zrobić, zjedzenie 100% CPU. W tym momencie klikam przycisk "Przerwa" i próbuję znaleźć to, co działa tak długo.Stary, gdzie jest moja nitka ?? (lub: zmień nazwę wątku puli wątków .NET - czy jest to możliwe?)

Problem polega na tym, że ta aplikacja ma ogromną liczbę wątków uruchomionych, a w momencie, gdy kliknęłam "Przerwa", punkt wykonywania przechodzi do wątku GUI, który prawdopodobnie po prostu robi "Poczekaj". Muszę następnie przebić się przez istniejące wątki (policzyłem je - tym razem mają 37!), Próbując znaleźć ten, który wykonywałem. Musiałbym spojrzeć na stos każdego z nich, dopóki nie znajdę tego, którego szukałem.

Wątek, który używam, jest wywołaniem asynchronicznym, więc działa na wątku puli wątków. Chciałbym nadać temu wątkowi opisową nazwę i zresetować jego nazwę na końcu operacji.

Problemem jest to, nieruchomości można ustawić tylko raz, potem on daje InvalidOperationException.

Wszelkie sugestie?

O tak, używam VS2005/.NET 2.0, ale jestem również ciekawy, czy nowsze wersje mają lepsze sposoby radzenia sobie z tym.

+0

Awansuj tylko dla swojego tytułu! (nie bardzo, świetne pytanie) –

Odpowiedz

4

zdefiniować własną nieruchomość 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"; 
    } 
} 

Można nawet napisać własne otoki że automagicznie otacza swoją zwrotnego akcji/delegat/asynchronicznej w tym z wykorzystaniem rachunku.

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

Wtedy, kiedy przestać debuggera, rzucić okiem na zawartość zmiennej ThreadMarker.ThreadNames i widać, które udało nici tkwią w swoich nazwach koparki.

+0

Jak to pomoże w identyfikacji wątku w debugerze? Czy rzeczywiście odbierze tę właściwość? Wewnętrzne pole używane dla nazwy to "m_Name", a nie "__Name" i nie jest to wątek statyczny. –

+0

Dodałem kod dla twojego problemu. Po uruchomieniu nie będzie można zmienić nazwy wątku. Możesz jednak użyć pola znacznika typu "threadstatic", które możesz sprawdzić, gdy zamrozisz aplikację, aby sprawdzić, który wątek jest uruchomiony, a który z procedur obsługi. –

Powiązane problemy