using System.Management a faux pas?

N

not_a_commie

Is using System.Management in general a faux pas? It seems, after some
web searching, that there is a fair amount of resistance to it because
of speed and portability.

I need to know how many CPU sockets there are. I'm using
System.Management to do this. It takes about two seconds to do this.
(Which, yes, is full-on crap for speed.) But what is the better way to
determine the number of CPU sockets in Windows version >= 5 with
a .NET >= 2.0 application?
 
N

Nicholas Paldino [.NET/C# MVP]

not_a_commie,

With the System.Management namespace, you are trading off performance
for ease-of-use, and maintainability (through a unified object model and
query syntax). I am sure that there is much faster code to find this out,
but it is most likely done with interop, which if not done correctly, can
impact ease-of-use and maintainability.

So in the end, it is a trade off, and like all trade offs, you have to
make the decision which one is better for your application's needs.
 
W

Willy Denoyette [MVP]

not_a_commie said:
Is using System.Management in general a faux pas? It seems, after some
web searching, that there is a fair amount of resistance to it because
of speed and portability.

I need to know how many CPU sockets there are. I'm using
System.Management to do this. It takes about two seconds to do this.
(Which, yes, is full-on crap for speed.) But what is the better way to
determine the number of CPU sockets in Windows version >= 5 with
a .NET >= 2.0 application?


Environment.ProcessorCount, returns the number of processors, but this is
not what you are looking for.
Getting the CPU unit count from WMI should however not take more than 50
msecs.
What OS and what WMI class are you using for this.

Willy.
 
W

Willy Denoyette [MVP]

Willy Denoyette said:
Environment.ProcessorCount, returns the number of processors, but this is
not what you are looking for.
Getting the CPU unit count from WMI should however not take more than 50
msecs.
What OS and what WMI class are you using for this.

Willy.


Following:
int processors;
SelectQuery query = new SelectQuery("select Deviceid from
Win32_Processor");
using(ManagementObjectSearcher searcher = new
ManagementObjectSearcher(query))
{
ManagementObjectCollection processor= searcher.Get();
processors = processor.Count;
}

takes 30...40msecs. when run on my box.
Note that the very first call can take some more time on some OS versions,
as the system has to start WMI (when not already).
started, anyway, this should be *much* less than 2 seconds, provided your
system is not running low on CPU or/and memory resources.

Willy.
 
N

not_a_commie

I'm using WinXP SP2 on a core 2 duo. I'm thinking that my timer is
getting thrown off because this is being loaded in a static
constructor with other assemblies being loaded at the same time.
Here's the code:

if (Environment.OSVersion.Version.Major >= 6 ||
Environment.OSVersion.Platform == PlatformID.Unix)
return; // the bug we're working around exists in WinXP and older

ManagementClass mc = new ManagementClass("Win32_Processor");
ManagementObjectCollection mos = mc.GetInstances(); // get all the
processors from the device manager
List<string> cpuSockets = new List<string>();

foreach (ManagementObject mo in mos)
{
string socketDesc =
mo.SystemProperties["SocketDesignation"].Value.ToString();
if(!cpuSockets.Contains(socketDesc))
cpuSockets.Add(socketDesc);
}

if (cpuSockets.Count > 1)
{
// my special handling here
}
 
N

not_a_commie

So can I do something like this?

"select unique SocketDesignation from Win32_Processor"
 
N

not_a_commie

So I thought that

"select SocketDesignation from Win32_Processor group by
SocketDesignation"

would work (I would just use the count rows returned from that query).
Alas, it does not. Is SocketDesignation not the same as
["SocketDesignation"].Value? Or does the "group by" in WQL just behave
in a fishy manner? This query throws an exception:

"select count(*) from Win32_Processor group by SocketDesignation"
 
W

Willy Denoyette [MVP]

not_a_commie said:
So can I do something like this?

"select unique SocketDesignation from Win32_Processor"


No, but if you are only interested in a single CPU's properties, you can do
the following to get at a specific instance.

string objPath = "Win32_Processor.DeviceId='CPU0'";
string socketType;
using(ManagementObject service = new ManagementObject( new
ManagementPath(objPath)))
{
socketType = service.Properties["SocketDesignation"].Value.ToString();
}

Willy.
 
W

Willy Denoyette [MVP]

not_a_commie said:
So I thought that

"select SocketDesignation from Win32_Processor group by
SocketDesignation"

would work (I would just use the count rows returned from that query).
Alas, it does not. Is SocketDesignation not the same as
["SocketDesignation"].Value? Or does the "group by" in WQL just behave
in a fishy manner? This query throws an exception:

"select count(*) from Win32_Processor group by SocketDesignation"


While WQL looks like SQL it is not a full fledged SQL.

Willy.
 
N

not_a_commie

No, but if you are only interested in a single CPU's properties, you can do
the following to get at a specific instance.
...
socketType = service.Properties["SocketDesignation"].Value.ToString();

I'm interested in the count of unique SocketDesignation values --
nothing else. It's creating instances of these objects that takes the
time, not the WQL. I was hoping to get all the information I needed
using WQL.
 
W

Willy Denoyette [MVP]

not_a_commie said:
No, but if you are only interested in a single CPU's properties, you can
do
the following to get at a specific instance.
...
socketType = service.Properties["SocketDesignation"].Value.ToString();

I'm interested in the count of unique SocketDesignation values --
nothing else. It's creating instances of these objects that takes the
time, not the WQL. I was hoping to get all the information I needed
using WQL.



What takes time is starting up the WMI service (when not actually running)
and connecting to the WMI Service (through LPC for local connections and
DCOM over SMB for remote connections). Creating an instance takes no
measurable time as these are static instances , stored in WMI's metabase. On
the slowest box available, the query below took less than 700msecs. to
finish the first query, following queries, that is after WMI was running,
finished in less than 150msec. Did you actually instrumented your code, in
order to see what is taking most of the time?

Note that GetInstances returns all instances of the class, that means that
the number of instances IS the number of sockets.

ManagementClass mc = new ManagementClass("Win32_Processor");
ManagementObjectCollection mos = mc.GetInstances();
int sockets = mos.Count;

Willy.
 
N

not_a_commie

Note that GetInstances returns all instances of the class, that means that
the number of instances IS the number of sockets.

That's not true. I have a dual core system. I have two instances of
Win32_Processor. The SocketDesignation.Value on both of them specify
the same thing, which is correct: there is only one socket on my box.
 
W

Willy Denoyette [MVP]

not_a_commie said:
That's not true. I have a dual core system. I have two instances of
Win32_Processor. The SocketDesignation.Value on both of them specify
the same thing, which is correct: there is only one socket on my box.

Oh I see, this class implementation looks terribly broken on XP, you have
two instances and only one socket!.
On Vista , it returns one instance per socket and the field "NumberOfCores"
returns 2 for a Core Duo, while NumberOfLogicalProcessors has a value of 2
or 4 depending whether each core is HT enabled, and 'SocketDesignation' has
the string that describes the CPU socket, like "Socket 939" for AMD Athlon
X2 or "Socket 478" or "Socket 479" for core duo's.
I'm afraid you will have to look at calling the Win32 API's to get reliable
info about this.

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top