C#有效地迭代和比较/识别WMI服务

时间:2013-07-11 15:56:27

标签: c# linq service foreach wmi

我正在查询远程服务器上的特定服务,以尝试确定这些服务的状态,并相应地启动/停止/暂停它们。

我的Server对象类的片段如下:

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" };

现在,当我希望从所有可用服务中找到我在小清单中定义的服务时,我的斗争开始发挥作用,以隔离它们并操纵它们。我已完成任务,但处理速度非常慢。我希望找到一个聪明,简化的解决方案。有什么想法吗?

这是我当前的( cringe )逻辑:

    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);
                    }
                }
            }
        }
    }

2 个答案:

答案 0 :(得分: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
            }

答案 1 :(得分:0)

您应首先剖析您的例行程序,以确切了解处理时间最长的内容。它是服务器的查询,它是启动服务吗?是吗?

我怀疑,因为您连接到远程服务器,大部分时间您的应用程序都在等待远程服务器响应或启动其服务。如果你能告诉服务器做某事但不等待它完成它会好得多。

ManagementObject包含InvokeMethod的几个重载,其中一些是异步的。我的猜测是,您可以通过异步启动服务来改进您的应用程序,这意味着您不会等待每项服务执行此操作:您只需告诉它启动,然后转到下一个服务并启动它,等等上。通过这种方式,您的应用程序不再等待远程服务器执行此操作。