Manejo asíncrono de eventos WMI en .NET

I am trying to run some processes remotely using WMI and the wait for the process to finish. Currently the event watcher is semi-synchronous using WaitForNextEvent which also has a timeout in case the something happens to the program. All this works well. I tried modifying this to asynchronous event handling but I get an Access Denied error when starting the event watcher. Now this would not be a big deal because I could stick with the semi-synchronous method, but there is one exception.

If, for some reason, during the execution of the program the machine restarts, freezes, or looses the network connection, the WaitForNextEvent does not throw a timeout exception, but blocks the thread indefinitely(I left it there for 10 minutes with no answer , timeout was 30 seconds). My question is: does anyone know if the event watcher can be set up in a specific way in order to timeout regardless of the connection, or to setup the client side in order to have access to asynchronous permissions. Normally, the first one would be preferred, but the second one is also an option.

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

I would like to know if ManagementeventWatcher has some options to return or timeout regardless of the connection, or if an asynchronous method can be used in order to capture events.

Solucion

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

preguntado el 28 de agosto de 12 a las 14:08

Just wanna say that I am trying to find a solution to this as well. I am doing some search on my own and according to my tests this only happens on Windows 2003. Please let me know what you find and I will get back here if I find anything. -

@Henrik this happens on every OS. The problem is that waitForNextEvent does not handle loss of connection. What I did is give a very small timeout, like 1-5 ms, and repeat until something is found. During this I also ping the remote PC, so the time window in which it can fail is really small. I have yet to find any other solution to this. -

Is it possible to post how your solution looks like? Thanks -

@Henrik posted workaround solution -

Cristi - why do you need the 1 millisecond timeout? I tested myself with 5 second timeout but it when it never found anything. Are you saying that the 1 millisecond prevents the event from being deleted? -

1 Respuestas

respondido 20 mar '15, 22:03

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.