2013-07-11 32 views
1

我正在查詢遠程服務器上的特定服務,試圖確定這些服務的狀態,並相應地啓動/停止/暫停它們。C#有效地迭代和比較/識別WMI服務

我的服務器對象類的一個片段如下:

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

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

我利用ManagementClass對象的連接到我的服務器作爲一種生活必需品(範圍,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)和watch因爲他們慢慢地填充我的屏幕。可怕!感謝您的貢獻。 – scniro