【问题标题】:C# Iterating and Comparing/Identifying WMI Services EffectivelyC# 有效地迭代和比较/识别 WMI 服务
【发布时间】:2013-07-11 15:56:26
【问题描述】:

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

我的Server对象类的一个sn-p如下:

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

【问题讨论】:

  • 您可以在每台服务器上找到服务名称时打折。那么当你找到它们时,你可以立即停止并转移到下一个服务器上吗?您可以在多个线程上运行。您需要进行分析并找出慢的地方。
  • 我同意多线程可能有助于多台服务器的进程。但是,对于只有一次服务器,此过程的速度慢得令人无法接受。我研究了 LINQ 语句,它可以将两个列表合并在一起。但是,我不能以保留 .InvokeMethod() 的方式合并

标签: c# linq service foreach wmi


【解决方案1】:

我已经解决了这个问题。我知道,我不是返回集合中的所有实例,而不是与字符串不可比较/不可过滤,而是使用 WQL(不是 SQL——烦人,没有 in 运算符)语句查询我想要的内容,本质上是在服务器上过滤我的结果在他们返回之前。性能显着提高。

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
            }

【讨论】:

    【解决方案2】:

    您应该首先对您的日常工作进行概要分析,以准确了解处理时间最长的内容。是服务器的查询,是启动服务,还是两者兼而有之?

    我怀疑由于您大部分时间都在连接到远程服务器,因此您的应用程序正在等待远程服务器响应或启动它们的服务。如果你能告诉服务器做某事而不是等待它完成会更好。

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

    【讨论】:

    • 连接到服务器花费的时间最长,但是,在以我的原始方法收集服务时,我会简单地使用 Console.WriteLine(serviceInstance) 并观察它们慢慢填充我的屏幕。可怕!感谢您的贡献。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    • 2015-01-07
    • 2017-05-02
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 2018-05-12
    相关资源
    最近更新 更多