WMI ManagementObjectSearcher Options

Posted on 2004-08-26
Last Modified: 2008-01-09
I'm running WMI queries on several machines on our network. What I am finding is that although a group of machines (same make, model, hardware, software platform) are physically located the same distance from me, and are plugged into the same switch, I'm getting large differences in the return time of the following query:

SELECT * FROM Win32_OperatingSystem

I generally get results in roughly 6 seconds, but sometimes the result return takes 1min+ . I'm trying to figure out if I can just force a timeout on a query using the Options property of the ManagementObjectSearcher class, but I'm not sure what options can be set here. Does anyone have any other thoughts why the delays may occur? It's not always the same delay length or from the same computers. It seems like it just randomly pauses. Our network usage hovers at a low 2%, and collisions are little to none, so I'm sure it's not a network issue. The TimeOut property of the Connection class doesn't work, cause I connect just fine, its the call to ManagementObjectSearcher.Get() that causes the delay. Thanks!

Question by:nemakcanada
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2

Expert Comment

ID: 11902354
funnily enough i am writing a similar WMI scanner.

I also noticed a big and differential delay between scans...i am not sure of the actual reason for this but i do have a solution.

use multi-threading, as in for each machine queue a call to the scan class in a new thread in the threadpool, this will automatically queue all your scans and will send out up to 25scans at the same time, ie you should recieve your results 25 times faster than before.

check out

for more info on threads

Author Comment

ID: 11902730
Good advice, I'm going to have to play around with the Thread priorities and sleep times cause this approach bumped up my CPU usage by 10 times. Ok, so here's what I have:

Main Application Thread
       ->creates multiple scanning threads

Suppose I want the application to terminate when scan is complete, how can I determine when all the the Threads I have created, are complete. I realize that there is an IsAlive property for each thread, but I'm basically creating my Threads like this:

while(this.current_machine_index < 200)
      RootScanner root = new RootScanner(ip);
      Thread scan_thread = new Thread(new ThreadStart(root.RunWMIScan));
      scan_thread.Priority = ThreadPriority.BelowNormal;

When I exit this loop, scan_thread no longer references the 195th thread I created for example, it now references thread 199, therefore scan_thread.IsAlive no refers to thread 199. Suppoer 199 returns faster that 195, I'd incorrectly terminiate the app. Any thoughts?


Expert Comment

ID: 11910057
why not create a simple array of Threads ?

somewhere past the class declaration
private Thread[] scan_thread;

somewhere in Form_Load or constructor:
scan_thread = new scan_thread[200];

somewhere in your code:
while (...)
scan_thread[index] = new Thread(ThreadStart(.......))

or am I completely missing the point ?

Accepted Solution

gav_jackson earned 250 total points
ID: 11910495
i used a threadpool, let me explain the code below.

1. get list of computers to scan into an array (i personally used a DirectorySearcher to retrieve my list but there are a number of different ways to acheive this)

2. Iterate through this list of computers

3. Using "ThreadPool.QueueUserWorkItem(new WaitCallback "
    Queue a call to "ThreadFunctions" passing the parameter "arrComputers[i]"

    This will automatically queue any calls until an available thread can take each call and process it individually, giving you a maximum of 25 'concurrent(ish)' calls to "ThreadFunctions"

*you can only pass one parameter when using "WaitCallback"

4. The private function threadfunctions calls the public method threadfunctions  
*dunno why it does this, all the examples i saw worked like this *shrugs* hey it works!

5. Do your wmi scan to "strComputerName" here

6. This is my attempt to figure out when the scans are finished by checking to see the number of available threads in the pool.
*i think this bit is flawed, im reading through it and it doesnt make any sense....but its a start

good luck

    private static void scanDomain(string strScanType)
      Scanner.myScanner gv = new Scanner.myScanner();
      string [] arrComputers = gv.getListComputers(strDomain);

      nNumberOfPCsToAudit = arrComputers.GetLength(0);
      for(int i = 0; i <= nNumberOfPCsToAudit; i++)
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadFunctions),arrComputers[i]);

    private static void ThreadFunctions(object strComputerName)
      ThreadFunctions((string) strComputerName);

    public static void ThreadFunctions(string strComputerName)
      //this is where you scan strComputerName

      int nWorkerThreads;
      int nPortThreads;
      int nMaxThreads;

      ThreadPool.GetMaxThreads(out nWorkerThreads, out nPortThreads);
      nMaxThreads = nWorkerThreads;

      ThreadPool.GetAvailableThreads(out nWorkerThreads, out nPortThreads);
      if(nWorkerThreads >= nMaxThreads)
        //Finished All Scans
        //Scanned " + strComputerName


Author Comment

ID: 11911588

I could create an array, but due to memory consumption issues, I'd rather not. The array could be anywhere from 300-1000 items in size for our internal network alone, let alone if we start using a scanner like this throughout the company 3000+.


Good call on checking the number of threads in the pool, it'll work good enough for me. I've created a configuration app for my scanner that will allow an end user to throttle the speed/cpu usage up and down based on a few things. By default, it uses the ThreadPool class, but it allows the user (an admin) to configure how many threads (1-24) and how long of a delay between thread execution so that no matter what machine we run this on, we can keep CPU usage down. Thanks for your help on this, I'll award you the points.

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

687 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question