2010-01-25 31 views
12

Đôi khi tôi thấy mình bước qua một ứng dụng trong chế độ Debug, cho đến khi tôi nhấn 'bước' trên một số dòng cụ thể và phải mất quá nhiều thời gian để làm điều gì đó, ăn CPU 100%. Tại thời điểm này, tôi nhấn nút 'Break' và cố gắng tìm những gì đang chạy quá lâu.Dude, chủ đề của tôi ở đâu ?? (hoặc: đổi tên một thread thread thread .net - có thể không?)

Vấn đề là, ứng dụng này có số lượng chủ đề khổng lồ đang chạy và tại thời điểm tôi nhấn 'Break', điểm thực hiện chuyển đến luồng GUI có thể chỉ là 'Chờ'. Sau đó tôi phải tìm kiếm các chủ đề hiện có (tôi đã đếm chúng - lần này chúng là 37!) Đang cố gắng tìm ra chủ đề tôi đang thực hiện. Tôi sẽ phải nhìn vào đống của mỗi người trong số họ cho đến khi tôi tìm thấy một trong những tôi đang tìm kiếm.

Chủ đề tôi đang chạy là một cuộc gọi không đồng bộ, do đó nó chạy trên một chuỗi luồng chủ đề. Tôi muốn đặt tên mô tả cho chủ đề này và đặt lại tên của nó ở cuối hoạt động.

Vấn đề là, thuộc tính chỉ có thể được đặt sau khi, sau đó nó cung cấp cho InvalidOperationException.

Mọi đề xuất?

Ồ vâng, tôi đang chạy VS2005/.NET 2.0 nhưng tôi cũng tò mò nếu các phiên bản mới hơn có cách tốt hơn để xử lý việc này.

+0

Upvote chỉ dành cho tiêu đề của bạn! (không thực sự, câu hỏi tuyệt vời) –

Trả lời

4

Xác định tài sản riêng bạn 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"; 
    } 
} 

Bạn thậm chí có thể viết wrapper của riêng bạn mà Automagically kết thúc tốt đẹp gọi lại hành động/đại biểu/async của bạn trong bản Tuyên Bố sử dụng này.

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

Sau đó, khi bạn ngừng trình gỡ rối, hãy xem nội dung của biến ThreadMarker.ThreadNames và bạn sẽ thấy chuỗi quản lý nào bị kẹt trong trình xử lý được đặt tên của bạn.

+0

Làm thế nào điều này sẽ giúp với việc xác định các chủ đề trong trình gỡ rối? Nó sẽ thực sự nhận tài sản này thay thế? Trường nội bộ được sử dụng cho tên là "m_Name" không phải là "__Name" và nó không phải là luồng tĩnh. –

+0

Tôi đã thêm một số mã cho sự cố của bạn. Bạn sẽ không thể đổi tên chuỗi chỉ khi nó đang chạy. Những gì bạn có thể làm mặc dù là sử dụng một lĩnh vực đánh dấu threadstatic mà bạn có thể kiểm tra khi bạn đóng băng ứng dụng của bạn để xem thread đang chạy mà xử lý của bạn. –