.NET 中的异步 WMI 事件处理

Posted

技术标签:

【中文标题】.NET 中的异步 WMI 事件处理【英文标题】:Asynchronous WMI Event handling in .NET 【发布时间】:2012-08-23 00:05:52 【问题描述】:

我正在尝试使用 WMI 远程运行一些进程并等待进程完成。目前,事件观察器是半同步的,使用WaitForNextEvent,它也有一个超时,以防程序发生某些事情。这一切运作良好。我尝试将其修改为异步事件处理,但在启动事件观察程序时出现访问被拒绝错误。现在这没什么大不了的,因为我可以坚持使用半同步方法,但有一个例外。

如果由于某种原因,在程序执行过程中机器重启、死机或失去网络连接,WaitForNextEvent 不会抛出超时异常,而是无限期地阻塞线程(我将它留在那里 10分钟没有回答,超时为 30 秒)。我的问题是:有谁知道是否可以以特定方式设置事件观察器以便无论连接如何都超时,或者设置客户端以便访问异步权限。通常,首选第一个,但也可以选择第二个。

ManagementEventWatcher w = new ManagementEventWatcher(managementScope,
    new WqlEventQuery(
        "select * from Win32_ProcessStopTrace where ProcessId=" + ProcessId));

w.Options.Timeout = new TimeSpan(0, 0, 0, 30);

var ev = w.WaitForNextEvent();

我想知道 ManagementeventWatcher 是否有一些选项可以返回或超时而不管连接如何,或者是否可以使用异步方法来捕获事件。

解决方案

ManagementEventWatcher w = new ManagementEventWatcher(managementScope,
    new WqlEventQuery(
        "select * from Win32_ProcessStopTrace where ProcessId=" + ProcessId));

w.Options.Timeout = new TimeSpan(0, 0, 0, 0, 1);
DateTime start = DateTime.Now;
while (Status == StatusNotStarted) //default status(just strings)

    try
    
        var ev = w.WaitForNextEvent();
        ReturnCode = (uint)ev.Properties["ExitStatus"].Value;
        Status = (ReturnCode == 0) ? StatusOk : StatusFailed;
    
    catch (ManagementException ex)
    
        if (!ex.Message.Contains("Timed out"))
        
            throw ex;
        
        try
        
            Ping p = new Ping();
            PingReply reply = p.Send(MachineIP);
            if (reply.Status != IPStatus.Success)
            
                Status = StatusFailed;
            
            else
            
                DateTime end = DateTime.Now;
                TimeSpan duration = end - start;
                if (duration.TotalMilliseconds > Timeout)
                
                    Status = StatusFailed;
                
            
        
    

【问题讨论】:

只想说我也在努力寻找解决方案。我自己做一些搜索,根据我的测试,这只发生在 Windows 2003 上。请告诉我你找到了什么,如果我找到任何东西,我会回到这里。 @Henrik 这发生在每个操作系统上。问题是 waitForNextEvent 不处理连接丢失。我所做的是给一个非常小的超时时间,比如 1-5 毫秒,然后重复直到找到一些东西。在此期间,我还 ping 远程 PC,因此它可能失败的时间窗口非常小。我还没有找到任何其他解决方案。 是否可以发布您的解决方案的外观?谢谢 @Henrik 发布了解决方法 Cristi - 为什么需要 1 毫秒超时?我用 5 秒的超时时间测试了自己,但它什么也没找到。你是说 1 毫秒防止事件被删除? 【参考方案1】:

这个答案描述了一种实现非阻塞 WaitForNextEvent() 的方法

https://social.msdn.microsoft.com/Forums/vstudio/en-US/c2b6a2f4-eb84-4bbb-acdb-bbef4b0611e6/nonblocking-managementeventwatcherwaitfornextevent?forum=csharpgeneral

希望对你有帮助

【讨论】:

以上是关于.NET 中的异步 WMI 事件处理的主要内容,如果未能解决你的问题,请参考以下文章

WCF 异步调用 - 事件处理程序中的异常

.NET中的异步

由于 open 函数中有时间冲突,WMI ADAP 无法处理 性能库

异步事件处理程序有时会挂在 Xamarin.Forms

ASP.NET 事件处理

Linux程序设计学习笔记——异步信号处理机制