Обнаружить новую тему, созданную в .NET - PullRequest
0 голосов
/ 08 ноября 2010

Я пытаюсь реализовать некоторые средства измерения производительности для нашего приложения Windows Forms, и я хотел бы определить, когда создается новый поток (в частности, из потока пользовательского интерфейса), и наблюдать, когда он завершается.Я знаю, что могу поймать событие завершения потока на

System.Windows.Forms.Application.ThreadExit 

Но мне нужно выяснить, когда новый поток вызывается с помощью ThreadPool (или BackgroundWorker, который использует ThreadPool под капотом).В идеале я также хотел бы получить StackFrame, откуда он вызывается.

Кто-нибудь знает способ сделать это?WMI возможно?

Спасибо.

Ответы [ 5 ]

3 голосов
/ 08 ноября 2010

Добавить собственную DLL в ваше приложение, которое запускает необходимую обработку на DLL_THREAD_ATTACH в DllMain .

Это единственный способ надежно обнаружить создание всех потоков в процессе.

РЕДАКТИРОВАТЬ: Это будет проблематично, поскольку управляемые потоки и собственные потоки не соответствуют 1-1.Я думаю, что вам, возможно, придется использовать поддержку отладки управляемых потоков, чтобы делать то, что вы хотите.Больно но это должно работать.Например, см. ICorDebugThread .

Представляет поток в процессе.Время жизни экземпляра ICorDebugThread совпадает с временем жизни потока, который он представляет.

и ICorDebugProcess имеет несколько полезных инструментов для вас.на самом деле не хочу писать отладчик, но вам нужен этот уровень проверки для ваших управляемых потоков.Возможно, материнская строка будет ICorDebugManagedCallback :: CreateThread .

Уведомляет отладчик о том, что поток начал выполнять управляемый код.1028 * обратный вызов.

1 голос
/ 08 ноября 2010

Я бы пошел сюда , если бы я был на твоем месте ...

CLR Profiling API позволяет вам подключать управляемые функции, чтобы ваш профилировщик вызывался при входе, выходе или выходе из функции через tailcall. Мы называем их крючками Enter / Leave / Tailcall или ELT. В этой специальной серии расследований, состоящей из нескольких частей, я раскрою правду об ELT. Сегодня я напишу об основах NGEN и о том, что мы называем «медленный путь» и «быстрый путь».

Затем попытайтесь создать фильтр методов и перехватывать вызовы конструктора Thread. Если бы это могло сработать, это могло бы быть зверским!

1 голос
/ 08 ноября 2010

Я думаю, вы могли бы использовать временного потребителя WMI с запросом вроде:

select * from __InstanceCreationEvent within 3 where
     TargetInstance ISA 'Win32_Thread'

Затем, учитывая поток, вы можете проверить дескриптор процесса и посмотреть, является ли оно вашим приложением.

0 голосов
/ 08 ноября 2010

Нечто подобное будет работать. Мне пришлось вставить разделение ('.'), Потому что он работал в Visual Studio в режиме отладки.

 var assy = Assembly.GetExecutingAssembly();
 var process = Process.GetProcesses().Where(a => assy.GetName().Name.Contains(a.ProcessName.Split('.')[0]));

        foreach (var p in process)
        {
            Console.WriteLine(p.Threads.Count);
        }
0 голосов
/ 08 ноября 2010

Это может быть более высокий уровень, чем вы ищете, но вы можете использовать Windows Performance Monitor для измерения нескольких показателей, связанных с процессами, включая количество потоков. Просто откройте его из панели управления | Административные инструменты | Спектакль. Затем выберите объект производительности «Обработка» для списка метрик.

В качестве альтернативы, если вы поддерживаете это приложение, вы можете установить собственные хуки, чтобы определить, когда запускается новый поток.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...