2013-07-11 2 views
1

Я работаю над запросом конкретных служб на удаленном сервере, пытаясь определить статус этих служб и запускать/останавливать/приостанавливать их соответственно.C# Итерация и сравнение/Идентификация служб WMI Эффективно

Фрагмент моего класса объекта сервера выглядит следующим образом:

public class Server 
{ 
    public ManagementClass Services { get; set; } 

    public List<string> TargetServices { get; set; } 
} 

Я делаю использование объекта ManagementClass для подключения к серверу как своего рода набор других предметов первой необходимости (Scope, ConnectionOptions и ManagementPath (. «Win32_Service») TargetedServices просто небольшой список услуг, которые я определил, которые я намерен нацеливаться всех услуг, возвращенных в моих результатах подключения пример моего TargetedService можно увидеть следующим образом:.

server.TargetedServices = new List<string>() { "ServiceA", "ServiceB" }; 

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

Вот мой текущий (передергивает) логика:

public void PingServices(List<Server> servers) 
    { 
     foreach(Server server in servers) 
     { 
      foreach(ManagementObject service in server.Services.GetInstances()) 
      { 
       foreach(string target in server.TargetServices) 
       { 
        if(service.GetPropertyValue("Name").ToString() == target) 
        { 
         service.InvokeMethod("StartService", null); 
        } 
       } 
      } 
     } 
    } 
+0

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

+0

Согласен, что несколько потоков могут помочь процессу для нескольких серверов. Однако этот процесс является неприемлемо медленным только для одного сервера. Я просмотрел инструкции LINQ, которые могут объединить два списка вместе. Однако я не могу объединить и таким образом, чтобы сохранить .InvokeMethod() – scniro

ответ

1

Я решил это. Я понимаю, что вместо того, чтобы возвращать все экземпляры в коллекции, которая не сопоставима/фильтруется для строк, я запрашиваю то, что хочу, с оператором WQL (не SQL-раздражающим, нет в операторе), по существу фильтруя мои результаты на сервере прежде чем они будут возвращены. Производительность заметно возросла.

string sql = string.Format("SELECT * From Win32_Service WHERE Name = {0}", string.Join(" OR Name =", server.TargetServices)); 

ManagementObjectSearcher searcher = new ManagementObjectSearcher(server.Services.Scope, new ObjectQuery() 
       { 
        QueryString = sql 
       }); 

      foreach (ManagementObject service in searcher.Get()) 
      { 
       service.InvokeMethod("StartService", null); 
       //My Target Services 
      } 
0

Вы должны сначала профиль рутины, чтобы обнаружить то, что занимает больше времени, чтобы обработать. Является ли это запросом серверов, является ли это запуском сервисов, так ли это?

Я подозреваю, что, поскольку вы подключаетесь к удаленным серверам большую часть времени, когда приложение сидит, ожидая, что удаленные серверы будут отвечать или запускать свои службы. Было бы намного лучше, если бы вы могли сказать серверу что-то сделать, но не ждать, пока он закончит.

ManagementObject содержит пару перегрузок для InvokeMethod, а некоторые из них асинхронны. Я предполагаю, что вы могли бы улучшить свое приложение, асинхронно отбрасывая свои услуги, а это означает, что вы не будете ждать, пока каждая служба сделает это: вы просто скажете, чтобы это началось, затем перейдите на следующую службу и запустите ее. на. Таким образом, ваше приложение больше не ждет, когда удаленный сервер сможет это сделать.

+0

Подключение к серверу занимает самое длинное, однако, при сборе сервисов в моем первоначальном методе я бы просто Console.WriteLine (serviceInstance) и смотреть поскольку они медленно заполняли мой экран. Ужасно! Спасибо за ваш вклад. – scniro