【问题标题】:Set Timeout On Remote WMI when RPC Server Is Unavailable当 RPC 服务器不可用时在远程 WMI 上设置超时
【发布时间】:2014-10-06 04:29:49
【问题描述】:

我有以下代码检查远程计算机上的服务状态。问题是,如果找不到远程计算机(它宕机什么的),那么ManagementObjectSearcher.Get() 方法需要 20 秒才能抛出“RPC 服务器不可用”的错误。在服务器不可用的情况下,我想明确声明我只希望它尝试一小段时间(比如 3 秒)。我关注了帖子 here,但它声明要在 ManagementObjectSearcher 上使用 Timeout 选项,但我的代码似乎忽略了该值(因为它声明它与集合无关)。这些选项有什么我忽略的吗?我也尝试过使用ReturnImmediatly 属性,但无济于事。

public static void WmiServiceCheck()
    {
        try
        {
            var computerName = "SomeInvalidComputer";
            var serviceName = "Power";
            var managementScope = new ManagementScope(string.Format(@"\\{0}\root\cimv2", computerName));
            var objectQuery = new ObjectQuery(string.Format("SELECT * FROM Win32_Service WHERE Name = '{0}'", serviceName));
            var searcher = new ManagementObjectSearcher(managementScope, objectQuery);
            searcher.Options.Timeout = new TimeSpan(0, 0, 0, 3); // Timeout of 3 seconds
            var managementObjectCollection = searcher.Get();
            var serviceState = managementObjectCollection.Cast<ManagementObject>().ToList().Single()["State"].ToString();
            /// Other stuff here
        }
        catch (Exception ex)
        {
        }
    }

【问题讨论】:

    标签: c# timeout wmi


    【解决方案1】:

    是的,不是那个。您要设置 ConnectionOptions.Timeout:

      var managementScope = new ManagementScope(...);
      managementScope.Options.Timeout = TimeSpan.FromSeconds(3);
    

    我测试的时候效果很好。

    请记住,3 秒属于低端,如果有一段时间没有查询请求,服务器可能不得不将大量代码交换到 RAM 中来处理请求。如果服务器以其他方式保持磁盘驱动器跳跃,那不一定是快速操作。如果您不介意偶尔的误报,请仅选择它。我个人在工作站上的时间从不低于 10 秒,这是在 Hard Knocks 学校学到的。服务器类机器的 20 秒是安全的。

    【讨论】:

    • 汉斯,抱歉耽搁了,但我将您的行添加到我上面列出的确切代码中,直接在我实例化 ManagementScope 之后,并且在查询 SomeInvalidComputer 时,它仍然需要 20-30秒返回错误The RPC server is unavailable。对我缺少的东西有什么想法吗?
    • 嗯,这很糟糕。我唯一能想到的是“SomeInvalidComputer”实际上并不是一个无效的计算机名称,并且可以在不触发超时的情况下正确联系。基本上,我警告过你的 Hard Knocks 场景。
    • 我们会的,它不能完全满足我的需求,但它似乎是问题的正确答案。也许某些底层 Windows 网络组件发生了一些奇怪的事情。感谢您的帮助。
    • @bigmac 如果您可以通过设置 Options.Timeout 更改初始 TCP 连接超时,我会感到惊讶。 MSDN 还说“此属性对 T:System.Management.ManagementScope.Connect 方法没有影响。”。所以我猜你看到的超时是默认的 TCP/IP 21 秒“连接”超时(有关详细信息,请参阅 serverfault.com/a/671453)。
    【解决方案2】:

    我意识到这是一个老问题,但它从未得到解决。这是我的解决方法。

    Dim wmiScope As New Management.ManagementScope("\\" & HOST_COMPUTER_HERE & "\root\cimv2")
    Dim exception As Exception = Nothing
    Dim timeRan As Integer = 0
    Dim wmiThread As Threading.Thread = New Threading.Thread(Sub() Wmi_Connect(wmiScope))
        wmiThread.Start()
        While wmiThread.ThreadState = Threading.ThreadState.Running
            Threading.Thread.Sleep(1000)
            timeRan += 1000
    'WmiThreadTimeout is a global variable set to 10,000 miliseconds.
                If timeRan >= WmiThreadTimeout Then
                    wmiThread = Nothing
                        exception = New Exception(HostName & " could not be connected to within the timeout period.")
                    End If
                    Exit While
                End If
            End While
    

    这是线程。

    Private Sub Wmi_Connect(ByRef wmiScope As Management.ManagementScope)
        Try
            wmiScope.Connect()
        Catch ex As System.Runtime.InteropServices.COMException
        End Try
    End Sub
    

    正如我所说,这是一种解决方法。它不会杀死线程,只是阻止它阻塞。 (我确实意识到将 Thread 对象设置为 Nothing 不会杀死线程。)

    【讨论】:

      【解决方案3】:

      这行得通。在 Task.Wait 行中更改超时。它将在 5 秒后停止尝试连接,您仍然会收到 RPC 连接异常

          public static bool Connect(string pc)
          {
              var task = new Task<bool>(() =>
              {
                  try
                  {
                      ManagementScope scope = new ManagementScope($"\\\\{pc}\\root\\cimv2");
      
                      scope.Connect();
      
                      return scope.IsConnected;
                  }
                  catch (Exception ex)
                  {
                      //Log ex
                      return false;
                  }
              });
      
              task.Start();
      
              return task.Wait(5000) && task.Result;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-19
        • 2021-02-16
        相关资源
        最近更新 更多