Ответ 1
Определите собственное свойство 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";
}
}
Вы можете даже написать свою собственную оболочку, которая автоматически завершает ваш ответ action/delegate/async в этом операторе 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);
Затем, когда вы остановите отладчик, просмотрите содержимое переменной ThreadMarker.ThreadNames, и вы увидите, какие управляемые потоки застревают в ваших именованных обработчиках.