Иногда я ступаю при применении в Режиме отладки, пока я не поразил 'шаг' в некоторую конкретную линию, и требуется слишком много времени, делая что-то, съедая выше на 100%-й центральный процессор. На данном этапе я нажал кнопку 'Break' и попытку найти то, что бежит, это занимает много времени.
Проблема, у этого приложения есть значительный объем управления нитей, и в то время, когда я поразил 'Разрыв', пункт выполнения идет в нить графический интерфейса пользователя, это, вероятно, просто делает 'Ожидание'. Я тогда должен охотиться через существующие нити (я посчитал их - на этот раз им 37 лет!) пытающийся найти тот я выполнял на. Я должен был бы посмотреть на стопку каждых из них, пока я не нахожу тот, который я искал.
Нить я продолжаюсь, является async, призывают, таким образом, она работает на нити фонда нити. Я хотел бы дать этой нити описательное имя и перезагрузить его имя в конце операции.
Проблема, собственность Thread.Name
может только быть установлен однажды, впоследствии это дает InvalidOperationException
.
Какие-либо предложения?
О, да я управляю VS2005/.NET 2.0, но мне также любопытно, если у более новых версий есть лучшие способы обращаться с этим.
Определите свое собственное свойство ThreadStation
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";
}
}
. Вы даже можете написать свою собственную обертку, которая автоматически обертывает ваше действие / делегат / async обратный вызов в этом с использованием оператора.
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);
Затем, когда вы остановите отладчик, посмотрите содержимое переменной Threammarker.threadnames, и вы увидите, какие управляемые потоки застряли в ваших именованных обработчиках.