Чувак, где моя нить?? (или: переименуйте нить фонда нити .NET - действительно ли это возможно?)

Иногда я ступаю при применении в Режиме отладки, пока я не поразил 'шаг' в некоторую конкретную линию, и требуется слишком много времени, делая что-то, съедая выше на 100%-й центральный процессор. На данном этапе я нажал кнопку 'Break' и попытку найти то, что бежит, это занимает много времени.

Проблема, у этого приложения есть значительный объем управления нитей, и в то время, когда я поразил 'Разрыв', пункт выполнения идет в нить графический интерфейса пользователя, это, вероятно, просто делает 'Ожидание'. Я тогда должен охотиться через существующие нити (я посчитал их - на этот раз им 37 лет!) пытающийся найти тот я выполнял на. Я должен был бы посмотреть на стопку каждых из них, пока я не нахожу тот, который я искал.

Нить я продолжаюсь, является async, призывают, таким образом, она работает на нити фонда нити. Я хотел бы дать этой нити описательное имя и перезагрузить его имя в конце операции.

Проблема, собственность Thread.Name может только быть установлен однажды, впоследствии это дает InvalidOperationException.

Какие-либо предложения?

О, да я управляю VS2005/.NET 2.0, но мне также любопытно, если у более новых версий есть лучшие способы обращаться с этим.

12
задан Cristi Diaconescu 25 January 2010 в 17:22
поделиться

1 ответ

Определите свое собственное свойство 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, и вы увидите, какие управляемые потоки застряли в ваших именованных обработчиках.

4
ответ дан 2 December 2019 в 23:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: