• (cs)

    It took me a while to figure this out, but the "wait up to a full day" thing is just a smokescreen. Here is The Real WTF:

    while (((window == IntPtr.Zero) ||
            (window != IntPtr.Zero && window == avoidWindow)) &&
        (i++ < max))

    If avoidWindow equals IntPtr.Zero (as it is if you call the 2-arg version of GetWindow), then this check will always fail, and the it will stay in the while loop for the entire timeout period, even if it finds the window before then.

    In other words, if you call the 2-arg version of GetWindow, and it doesn't find the window immediately (the statement before entering the while loop), it will wait the whole 24 hours.

  • Jonathan (unregistered) in reply to BrownHornet
    BrownHornet:
    It took me a while to figure this out, but the "wait up to a full day" thing is just a smokescreen. Here is The Real WTF:
    while (((window == IntPtr.Zero) ||
            (window != IntPtr.Zero && window == avoidWindow)) &&
        (i++ < max))
    If avoidWindow equals IntPtr.Zero (as it is if you call the 2-arg version of GetWindow), then this check will always fail, and the it will stay in the while loop for the entire timeout period, even if it finds the window before then.

    In other words, if you call the 2-arg version of GetWindow, and it doesn't find the window immediately (the statement before entering the while loop), it will wait the whole 24 hours.

    Not true. If the 'window = Win32API.FindWindow(className, title);' finds a window then the while loop will exit.

    window == IntPtr.Zero; //false, it equals the non-zero window value. window != IntPtr.Zero; //true. window == avoidWindow; //false, it equals the non-zero window value.

    So that is false || (true && false) false || false false

    so the while loop terminates.

  • Jon (unregistered)

    The real wtf is assuming that a day has 86400 seconds. Due to daylight savings, they may have 82800 or 90000 seconds. Due to the occasional leap second, some days even have 86401 seconds.

  • jou (unregistered) in reply to Jon
    Jon:
    [...]Due to daylight savings, they may have 82800 or 90000 seconds.[...]

    Only on the day when the clock shifts back from DST to normal time... And when DST starts, the day has only 79200 seconds.

    Since we're on the topic of daylight saving time:

    http://www.nwanews.com/adg/Editorial/187608:
    [...]As you know, Daylight Saving Time started almost a month early this year. You would think that members of Congress would have considered the warming effect that an extra hour of daylight would have on our climate. Or did they ?[...]

    I almost died laughing when I read this :)

  • (cs) in reply to Jonathan
    Jonathan:
    BrownHornet:
    It took me a while to figure this out, but the "wait up to a full day" thing is just a smokescreen. Here is The Real WTF:
    while (((window == IntPtr.Zero) ||
            (window != IntPtr.Zero && window == avoidWindow)) &&
        (i++ < max))
    If avoidWindow equals IntPtr.Zero (as it is if you call the 2-arg version of GetWindow), then this check will always fail, and the it will stay in the while loop for the entire timeout period, even if it finds the window before then.

    In other words, if you call the 2-arg version of GetWindow, and it doesn't find the window immediately (the statement before entering the while loop), it will wait the whole 24 hours.

    Not true. If the 'window = Win32API.FindWindow(className, title);' finds a window then the while loop will exit.

    window == IntPtr.Zero; //false, it equals the non-zero window value. window != IntPtr.Zero; //true. window == avoidWindow; //false, it equals the non-zero window value.

    So that is false || (true && false) false || false false

    so the while loop terminates.

    Hear fjuckin' hear! <standing ovation> At last, someone's got it. There's no real WTF here, just a rather overly-long timeout that you would expect in practice will never come into play.

    Jeebus, is our industry in a sorry state.

  • clm (unregistered) in reply to ThePants999
    ThePants999:
    Does nobody understand Zygo's comment?
    Thank you! The comment seemed clear enough to me (except for the off-by-a-factor-of-four slip-up on point 3) that I couldn't understand how so many people were misinterpreting it.
  • (cs) in reply to Jonathan
    Jonathan:
    BrownHornet:
    It took me a while to figure this out, but the "wait up to a full day" thing is just a smokescreen. Here is The Real WTF:
    while (((window == IntPtr.Zero) ||
            (window != IntPtr.Zero && window == avoidWindow)) &&
        (i++ < max))
    If avoidWindow equals IntPtr.Zero (as it is if you call the 2-arg version of GetWindow), then this check will always fail, and the it will stay in the while loop for the entire timeout period, even if it finds the window before then.

    In other words, if you call the 2-arg version of GetWindow, and it doesn't find the window immediately (the statement before entering the while loop), it will wait the whole 24 hours.

    Not true. If the 'window = Win32API.FindWindow(className, title);' finds a window then the while loop will exit.

    window == IntPtr.Zero; //false, it equals the non-zero window value. window != IntPtr.Zero; //true. window == avoidWindow; //false, it equals the non-zero window value.

    So that is false || (true && false) false || false false

    so the while loop terminates.

    I stand corrected. I must have had a serious brain cramp yesterday.
  • Jon (unregistered) in reply to jou
    jou:
    Only on the day when the clock shifts back from DST to normal time... And when DST starts, the day has only 79200 seconds.
    It's 82800, unless you're using double DST. :)
  • Maxam (unregistered)

    The only WTF I can see is that the timeout is enforced using a fixed number of 1/4 second thread sleeps (which ends up becoming more and more inaccurate) instead of just checking the current time vs. the time elapsed from the start of the call.

    Other than that, it seems like a normal function with an overly-long default timeout.

  • Igor (unregistered)

    There are a lot of WTFs in here:

    1. Hardcoding a value (86400) all over the source code instead of using const int.

    2. Using 250 ms Sleep() instead of say 3 or 5 seconds so you don't burn so much CPU cycles.

    3. If the caller passes window name as a parameter to FindWindow(), if the window belongs to the same process and if it is unresponsive, the caller of FindWindow() will also become unresponsive.

    4. If this function is by any chance called from an UI thread, Sleep() is a Bad Thing(TM).

    5. This code searches only top-level windows

    6. If the className and title are both NULL, all top-level windows will match and if avoidWindow is specified (not NULL) it will perform linear search through all the top-level windows every 250 ms until the right window is found

    7. There are other, more efficient ways to communicate between processes and threads than by looking for window handle and using it to send messages.

    Finally, the code comment in the OP is misleading since in 99% of the cases this code won't wait for 24 hours.

  • charles (unregistered)

    I think that would be more like 4 days, and possibly longer because of the 250 millisecond sleep that was added in there.

  • (cs) in reply to Jonathan
    Jonathan:
    BrownHornet:
    It took me a while to figure this out, but the "wait up to a full day" thing is just a smokescreen. Here is The Real WTF:
    while (((window == IntPtr.Zero) ||
            (window != IntPtr.Zero && window == avoidWindow)) &&
        (i++ < max))
    If avoidWindow equals IntPtr.Zero (as it is if you call the 2-arg version of GetWindow), then this check will always fail, and the it will stay in the while loop for the entire timeout period, even if it finds the window before then.

    In other words, if you call the 2-arg version of GetWindow, and it doesn't find the window immediately (the statement before entering the while loop), it will wait the whole 24 hours.

    Not true. If the 'window = Win32API.FindWindow(className, title);' finds a window then the while loop will exit.

    window == IntPtr.Zero; //false, it equals the non-zero window value. window != IntPtr.Zero; //true. window == avoidWindow; //false, it equals the non-zero window value.

    So that is false || (true && false) false || false false

    so the while loop terminates.

    And that's a WTF: The condition is more complex then required, could have been:
    while ((window == IntPtr.Zero ||               window == avoidWindow) && (i++ < max))
  • elainao (unregistered)
    Comment held for moderation.

Leave a comment on “Patiently Waiting Forever”

Log In or post as a guest

Replying to comment #:

« Return to Article