4

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.

Solution

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;
                }
            }
        }
    }
}
Community
  • 1
  • 1
Cristi M
  • 446
  • 4
  • 13
  • 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. – serializer Sep 07 '12 at 19:05
  • @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. – Cristi M Sep 09 '12 at 10:46
  • Is it possible to post how your solution looks like? Thanks – serializer Sep 10 '12 at 07:17
  • @Henrik posted workaround solution – Cristi M Sep 11 '12 at 08:11
  • 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? – serializer Sep 25 '12 at 13:15
  • The timeout given to WaitForNextEvent is the window in which the machine could freeze. When given a 1ms timeout, this window is very short, and the chance of the machine freezing in the exact same moment is very small. – Cristi M Sep 25 '12 at 13:36
  • In my situation I tested with 5 second timeout and created and external timer that killed it it hang longer than ten seconds. The problem is that, it waited, killed, reconnected for 3 hours even though the script takes about 30 seconds. I am not sure how long time the result is stored in WMI because maybe it is better to **query instead** of using event? I tried using 1 millisecond but that took too much cpu for my taste and I am not sure it will solve the problem for the end user. – serializer Sep 25 '12 at 16:33
  • In my case I am the end user, the script is just means to an end. The problem is that I cannot kill the thread which waits for the event(I tried numerous ways). Note that once started, all the events are put in a queue, so if an event happens in a moment where you are processing the previous event, the current event will not be lost. Oh, and the cpu problem, I "fixed" it with a short sleep in-between. @Henrik – Cristi M Sep 26 '12 at 08:56

1 Answers1

0

This answer describes a way of implementing a non-blocking WaitForNextEvent()

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

Hope this helps