我正在尝试使用 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;
}
}
}
}
}