Solved

WMI ManagementObjectSearcher Options

Posted on 2004-08-26
5
1,846 Views
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!

Brian
0
Comment
Question by:nemakcanada
  • 2
  • 2
5 Comments
 
LVL 1

Expert Comment

by:gav_jackson
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

http://www.yoda.arachsys.com/csharp/threadstart.html

for more info on threads
0
 

Author Comment

by:nemakcanada
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;
      scan_thread.Start();
}

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?
       

0
 
LVL 4

Expert Comment

by:somnatic
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(.......))
scan_thread[index].Start;
...
}


or am I completely missing the point ?
0
 
LVL 1

Accepted Solution

by:
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)
    {  
     //1
      Scanner.myScanner gv = new Scanner.myScanner();
      string [] arrComputers = gv.getListComputers(strDomain);

      nNumberOfPCsToAudit = arrComputers.GetLength(0);
   
      //2
      for(int i = 0; i <= nNumberOfPCsToAudit; i++)
      {
        if(arrComputers[i]!="")
        {
            //3
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadFunctions),arrComputers[i]);
        }
    }

    private static void ThreadFunctions(object strComputerName)
    {
       //4
      ThreadFunctions((string) strComputerName);
    }

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

      //6.
      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
      }
      else
      {
        //Scanned " + strComputerName
      }

    }
0
 

Author Comment

by:nemakcanada
ID: 11911588
somnatic.

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+.

gav_jackson

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.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…

912 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now