Timer function doesn't listen to lock

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Zytan

    Timer function doesn't listen to lock

    I have a Timer class set to trigger every second. The Tick function
    that is called every second uses a lock to prevent multiple ticks from
    executing the same code at the same time. The code within calls a
    Visual Basic input message box, which is synchronous, it waits until
    you enter some input, and press enter. But, this message box pops up
    every second regardless if the old ones have finished. The timer's
    Tick function is called over and over, and runs the code in the lock,
    totally ignoring the lock. Why? Something to do with threads? But,
    that's just what locks are FOR. The lock variable = new object(), so
    it should be fine.

    Zytan
  • Zytan

    #2
    Re: Timer function doesn't listen to lock

    Btw, I'm using System.Windows. Forms.Timer.

    Should I just use System.Timers.T imer, instead, and use
    Timer.AutoReset , to make the time tick ONLY once, and I'll start it up
    again after it ticks? (That should be a solution, but I'd still like
    to know what is going on with the lock that's not working above......)

    Zytan

    Comment

    • Peter Duniho

      #3
      Re: Timer function doesn't listen to lock

      On Wed, 16 Jul 2008 14:25:54 -0700, Zytan <zytanlithium@g mail.comwrote:
      I have a Timer class set to trigger every second. The Tick function
      that is called every second uses a lock to prevent multiple ticks from
      executing the same code at the same time. The code within calls a
      Visual Basic input message box, which is synchronous, it waits until
      you enter some input, and press enter. But, this message box pops up
      every second regardless if the old ones have finished. The timer's
      Tick function is called over and over, and runs the code in the lock,
      totally ignoring the lock. Why? Something to do with threads? But,
      that's just what locks are FOR. The lock variable = new object(), so
      it should be fine.
      Your question is vague. But I'll make a guess.

      Whatever timer class you're using (there are no less than three in .NET
      and you're not specific about which one you're using...I'm guessing
      System.Windows. Forms.Timer, since that one I know off the top of my head
      has a Tick event), undoubtedly the Tick event is being raised on the same
      thread each time. The lock() statement only prevents multiple threads
      from entering the same code. Any given thread, once it's successfully
      obtained the lock, can reenter the same lock()-protected code arbitrarily
      many times.

      If you don't want the message box displayed with each tick of the timer,
      just disable the timer before you show the message box and reenable it
      when the message box is dismissed. You can't use lock() for the purpose
      you're trying to use it for.

      For future reference, the debugger is a great way to explore what's
      actually going on. For example, in this particular case, you could have
      just set a breakpoint where you show the message box. Then, the second
      time you hit the breakpoint, you could look at the call stack. At that
      point, you'd find that in the same call stack was the previous call that
      showed the message box.

      With that information, you could then successfully reason that the message
      box is getting shown in the same thread each time, from which you could
      then infer that the lock() statement isn't going to help. Even if you
      were a bit uncertain about the rules for how lock() works, just knowing
      what was actually going on would probably have given you that "aha!"
      moment needed to figure things out. :)

      Pete

      Comment

      • Ignacio Machin ( .NET/ C# MVP )

        #4
        Re: Timer function doesn't listen to lock

        On Jul 16, 5:25 pm, Zytan <zytanlith...@g mail.comwrote:
        I have a Timer class set to trigger every second.  The Tick function
        that is called every second uses a lock to prevent multiple ticks from
        executing the same code at the same time.  The code within calls a
        Visual Basic input message box, which is synchronous, it waits until
        you enter some input, and press enter.  But, this message box pops up
        every second regardless if the old ones have finished.  The timer's
        Tick function is called over and over, and runs the code in the lock,
        totally ignoring the lock.  Why?  Something to do with threads?  But,
        that's just what locks are FOR.  The lock variable = new object(), so
        it should be fine.
        >
        Zytan
        Hi,

        You cannot call a UI from a thread other than the UI. Are you using
        Control.Invoke?

        Comment

        • Ignacio Machin ( .NET/ C# MVP )

          #5
          Re: Timer function doesn't listen to lock

          On Jul 16, 5:31 pm, Zytan <zytanlith...@g mail.comwrote:
          Btw, I'm using System.Windows. Forms.Timer.
          >
          Should I just use System.Timers.T imer, instead, and use
          Timer.AutoReset , to make the time tick ONLY once, and I'll start it up
          again after it ticks?  (That should be a solution, but I'd still like
          to know what is going on with the lock that's not working above......)
          >
          Zytan
          can you post your code?

          Comment

          • Zytan

            #6
            Re: Timer function doesn't listen to lock

            Whatever timer class you're using (there are no less than three in .NET
            and you're not specific about which one you're using...I'm guessing
            System.Windows. Forms.Timer, since that one I know off the top of my head
            has a Tick event),
            Yes.
            undoubtedly the Tick event is being raised on the same
            thread each time. The lock() statement only prevents multiple threads
            from entering the same code.
            Ah, of COURSE!
            Thank you.
            If you don't want the message box displayed with each tick of the timer,
            just disable the timer before you show the message box and reenable it
            when the message box is dismissed. You can't use lock() for the purpose
            you're trying to use it for.
            Exactly. I already knew the solution, it just bugged me that I
            couldn't figure out why lock() wasn't working. But, it's the same
            thread, of course!!

            In fact, the other Timer classes are better, since you can get them to
            'tick' just once, I believe, so there's absolutely NO chance of it
            ticking twice, so you can make sure to do the work first, and then
            restart it after.
            For future reference, the debugger is a great way to explore what's
            actually going on. For example, in this particular case, you could have
            just set a breakpoint where you show the message box. Then, the second
            time you hit the breakpoint, you could look at the call stack. At that
            point, you'd find that in the same call stack was the previous call that
            showed the message box.
            I use the debugger quite often, but this information wouldn't have
            made me realize my error, since I would have expected the same call
            stack. I just wasn't thinking that the same thread doesn't listen to
            locks. Stupid.
            Even if you
            were a bit uncertain about the rules for how lock() works, just knowing
            what was actually going on would probably have given you that "aha!"
            moment needed to figure things out. :)
            Good point! :)

            Zytan

            Comment

            • Zytan

              #7
              Re: Timer function doesn't listen to lock

              can you post your code?

              Already found the error of my ways in another post! :)

              Zytan

              Comment

              • Zytan

                #8
                Re: Timer function doesn't listen to lock

                You cannot call a UI from a thread other than the UI. Are you using
                Control.Invoke?
                Nope, I was just NOT realizing that lock() will not prevent the SAME
                THREAD from getting into it....... I should know this since I've done
                recursion with locks, and I've been bitten by this before.

                Zytan

                Comment

                • Zytan

                  #9
                  Re: Timer function doesn't listen to lock

                  Pete, I just had to write again to thank you. You have no idea how
                  much TIME you are saving me and how useful you're replies are.
                  Sometimes little bugs like this, even though I should know better, can
                  take up a good half hour or more, sometimes several hours, and stress
                  and frustration, so I appreciate the time you spend to clear up these
                  little matters. All the best, and have a great day! :)

                  Zytan

                  Comment

                  • henk holterman

                    #10
                    Re: Timer function doesn't listen to lock

                    Zytan wrote:
                    I have a Timer class set to trigger every second. ...


                    Zytan, you really should show some code. Then we will tell what you did
                    wrong (-:).

                    -hh-

                    Comment

                    • Peter Duniho

                      #11
                      Re: Timer function doesn't listen to lock

                      On Wed, 16 Jul 2008 14:46:25 -0700, Zytan <zytanlithium@g mail.comwrote:
                      [...]
                      In fact, the other Timer classes are better, since you can get them to
                      'tick' just once, I believe, so there's absolutely NO chance of it
                      ticking twice, so you can make sure to do the work first, and then
                      restart it after.
                      If you know you always specifically need a "one-shot" timer, yes...I'd
                      agree. They do, of course, introduce the complication of being raised on
                      a different thread, but it's possible that in your case, you don't
                      actually need the single-threaded behavior of the Forms.Timer class, or
                      that you feel that having to use Control.Invoke( ) is a suitable trade-off
                      for getting more deterministic timer behavior.

                      That said, with a one-second interval, assuming you disable the timer the
                      moment the event is raised, I doubt there's any realistic chance of the
                      timer getting to be raised more than once, assuming you're not already
                      abusing the GUI thread. Even if there was a chance, a simple boolean flag
                      would suffice to protect the handling of the event, by allowing you to
                      simply ignore re-entrant ticks of the timer.

                      Either way should be a workable solution.

                      And in another post:

                      On Wed, 16 Jul 2008 14:52:17 -0700, Zytan <zytanlithium@g mail.comwrote:
                      Pete, I just had to write again to thank you. You have no idea how
                      much TIME you are saving me and how useful you're replies are. [...]
                      You're very welcome. For what it's worth, I think a lot of times it's
                      just a matter of having someone else look at the problem. Often the only
                      reason a person's having a problem is that they are too close to the
                      implementation to see the mistake. They already know exactly what they
                      _meant_ for it to do, making it difficult or impossible to see what it
                      actually does.

                      In other words, pretty much anyone who's familiar with the same part of
                      the framework you're using could identify the same issue. I just happened
                      to be the first to note your question.

                      But regardless, I appreciate the comment, and of course you're welcome for
                      the help. :)

                      Pete

                      Comment

                      • Zytan

                        #12
                        Re: Timer function doesn't listen to lock

                        If you know you always specifically need a "one-shot" timer, yes...I'd
                        agree. They do, of course, introduce the complication of being raised on
                        a different thread
                        Yes, I noticed that, since I was updating GUI controls in the tick
                        handler. I don't think this will pose a problem, though. Thanks for
                        the warning.
                        >, but it's possible that in your case, you don't
                        actually need the single-threaded behavior of the Forms.Timer class, or
                        that you feel that having to use Control.Invoke( ) is a suitable trade-off
                        for getting more deterministic timer behavior.
                        I have no issues using Control.Invoke( ), I am comfortable with it.
                        That said, with a one-second interval, assuming you disable the timer the
                        moment the event is raised, I doubt there's any realistic chance of the
                        timer getting to be raised more than once, assuming you're not already
                        abusing the GUI thread. Even if there was a chance, a simple boolean flag
                        would suffice to protect the handling of the event, by allowing you to
                        simply ignore re-entrant ticks of the timer.
                        Very true.
                        You're very welcome. For what it's worth, I think a lot of times it's
                        just a matter of having someone else look at the problem. Often the only
                        reason a person's having a problem is that they are too close to the
                        implementation to see the mistake. They already know exactly what they
                        _meant_ for it to do, making it difficult or impossible to see what it
                        actually does.
                        Yup, just like when you read an essay you wrote yourself, you tend to
                        read what you MEANT to write, and not what you actually wrote, so a
                        second set of eyes are a godsend.

                        Thanks again!

                        Zytan

                        Comment

                        • Zytan

                          #13
                          Re: Timer function doesn't listen to lock

                          Zytan, you really should show some code. Then we will tell what you did
                          wrong (-:).
                          Pete already caught my mistake! But, thanks, nonetheless! :)

                          Zytan

                          Comment

                          Working...