System.Diagnostic.Process && Threads

  • Thread starter Thread starter Rami
  • Start date Start date
R

Rami

Hi,

I have the following problem. In my application I'm starting a process using
System.Diagnostic.Process class. New process opens some threads. I want to
know what was the maximum threads number during process execution. The only
way to get process threads is to use Threads property but it only gives
information about threads in the moment of calling property. So it is
impossible to get maximum threads number using it. How can I achieve this?
 
Rami said:
Hi,

I have the following problem. In my application I'm starting a process
using System.Diagnostic.Process class. New process opens some threads. I
want to know what was the maximum threads number during process execution.
The only way to get process threads is to use Threads property but it only
gives information about threads in the moment of calling property. So it
is impossible to get maximum threads number using it. How can I achieve
this?


It's possible, but it's not a trivial task. Why do you need this info what
OS are running this on?

Willy.
 
It's possible, but it's not a trivial task. Why do you need this info what
OS are running this on?

My OS are both Windows XP and Windows 2003. I need this info to present some
statistics about program.....

I've tried to achieve this using hook's but .NET Framework doesn't allow to
use global hooks...
 
Rami said:
My OS are both Windows XP and Windows 2003. I need this info to present some
statistics about program.....
You can use the performance counters .NET exposes. The ".NET CLR
LocksAndThreads" performance objects contains these. Programmatic access is
possible with the PerformanceCounter class, but you could also use the
built-in tools for aggregating and graphing these.

You cannot obtain an exact maximum count with this or with
Process.Threads.Count; an approximation based on periodic sampling is the
best you can do. If you really need an exact maximum then you should either
modify the program code to keep track of created threads itself or use
unmanaged code to run the process as a debugger and keep a count for
CREATE_THREAD_DEBUG_EVENT and EXIT_THREAD_DEBUG_EVENT.
 
Rami said:
My OS are both Windows XP and Windows 2003. I need this info to present
some statistics about program.....

I've tried to achieve this using hook's but .NET Framework doesn't allow
to use global hooks...


Ok, XP, WS2003 and higher come with a kernel trace event provider, you can
register an handler to receive Process start/stop and Thread start/top
events.
The easiest way to receive such events, is by by using the
System.Management.ManagementEventWatcher.
You should register four event watchers , a pair for the process events and
another pair for the thread start events.
In your thread event handlers, you should maintain a list of the current
threads per process, while your process handlers should maintain a list of
current processes.
Following is a small sample that illustrates the core, it simply displays
the ThreadId and ProcessId properties associated with a specific event. I
have used different color for each event, probably you will have to change
these to suit your needs.
Note that the handlers run on threadpool threads, so watch out when updating
shared resources from these handlers.

using System;
using System.Management;

class Application {
static object locker = new object();
public static void Main(string[] args)
{
WqlEventQuery pq = new WqlEventQuery();
pq.EventClassName = "Win32_ProcessStartTrace";
WqlEventQuery qt1 = new WqlEventQuery();
qt1.EventClassName = "Win32_ThreadStartTrace";
WqlEventQuery qt2 = new WqlEventQuery();
qt2.EventClassName = "Win32_ThreadStopTrace";
using(ManagementEventWatcher wp = new ManagementEventWatcher(pq))
using(ManagementEventWatcher wt1 = new ManagementEventWatcher(qt1))
using(ManagementEventWatcher wt2 = new ManagementEventWatcher(qt2))
{
wp.EventArrived += new
EventArrivedEventHandler(ProcessStartEventArrived);
wt1.EventArrived += new
EventArrivedEventHandler(ThreadStartEventArrived);
wt2.EventArrived += new
EventArrivedEventHandler(ThreadStopEventArrived);
wp.Start();
wt1.Start();
wt2.Start();
Console.ReadLine(); // block main thread for test purposes only
Console.ResetColor();
wp.Stop();
wt1.Stop();
wt2.Stop();
}
}
static void ProcessStartEventArrived(object sender,
EventArrivedEventArgs e) {
lock(locker)
{
Console.ForegroundColor = ConsoleColor.Red;
// Dump all of the process properties
foreach(PropertyData pd in e.NewEvent.Properties)
Console.WriteLine("{0} : {1}",pd.Name, pd.Value);
}
}
static void ThreadStartEventArrived(object sender, EventArrivedEventArgs e)
{
lock(locker)
{
Console.ForegroundColor = ConsoleColor.Green;
PropertyData pd1 = e.NewEvent.Properties["ProcessId"];
PropertyData pd2 = e.NewEvent.Properties["ThreadId"];
Console.WriteLine("{0}: {1} {2}: {3}", pd1.Name, pd1.Value,
pd2.Name, pd2.Value);
}
}

static void ThreadStopEventArrived(object sender, EventArrivedEventArgs
e) {
lock(locker)
{
Console.ForegroundColor = ConsoleColor.Yellow;
PropertyData pd1 = e.NewEvent.Properties["ProcessId"];
PropertyData pd2 = e.NewEvent.Properties["ThreadId"];
Console.WriteLine("{0}: {1} {2}: {3}", pd1.Name, pd1.Value,
pd2.Name, pd2.Value);
}
}
}


Willy.
 
Ok, XP, WS2003 and higher come with a kernel trace event provider, you can
register an handler to receive Process start/stop and Thread start/top
events.

Thanks, it's good idea and it fullfils my requirments. Thanks for the
example too.

Regards,
Radek
 
Back
Top