473,223 Members | 1,749 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,223 software developers and data experts.

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
Jul 16 '08 #1
12 4432
Btw, I'm using System.Windows.Forms.Timer.

Should I just use System.Timers.Timer, 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
Jul 16 '08 #2
On Wed, 16 Jul 2008 14:25:54 -0700, Zytan <zy**********@gmail.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
Jul 16 '08 #3
On Jul 16, 5:25*pm, Zytan <zytanlith...@gmail.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?

Jul 16 '08 #4
On Jul 16, 5:31*pm, Zytan <zytanlith...@gmail.comwrote:
Btw, I'm using System.Windows.Forms.Timer.

Should I just use System.Timers.Timer, 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?
Jul 16 '08 #5
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
Jul 16 '08 #6
can you post your code?

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

Zytan

Jul 16 '08 #7
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

Jul 16 '08 #8
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
Jul 16 '08 #9
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-

Jul 16 '08 #10
On Wed, 16 Jul 2008 14:46:25 -0700, Zytan <zy**********@gmail.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 <zy**********@gmail.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
Jul 16 '08 #11
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

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

Zytan
Jul 16 '08 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Jinlin | last post by:
I found a interesting problem in C# and couldn't explain it. The code to reproduce it is very simple: 1. Create a windows application in C#. 2. Listen to the activated event on the default form...
3
by: Mr. B | last post by:
My current app has a timer that I kick ON in my Form1_Load as follows: ' Set Up the Timer Function Dim t As New System.Timers.Timer(12000) ' 1000 = 1 Second t.Enabled = True ' False to Turn OFF...
3
by: Nico Grubert | last post by:
Hi there, on a Linux machine running Python 2.3.5. I want to create a file 'newfile' in a directory '/tmp' only if there is no file 'transfer.lock' in '/temp'. A cronjob creates a file...
4
by: Naveen Mukkelli | last post by:
Hi, Currently I'm using System.Threading.Timer to perform some tasks periodically, lets say every minute. How can we disable this timer(System.Threading.Timer) so that the time spent in the...
9
by: Brett | last post by:
I have a timer enabled on a form with an interval of 200. I place a break point on the first line in the timer tick event, which is a try. After a few events go on, the timer seems to stop. My...
4
by: Ben | last post by:
Hello everybody I got confused by this problem for which I don't have a logical explanation. There is a Thread (ThreadA) which receives Events from another system thread (ThreadS). ThreadA then...
5
by: Tony Gravagno | last post by:
I have a class that instantiates two Timer objects that fire at different intervals. My class can be instantiated within a Windows Form or from a Windows Service. Actions performed by one of the...
5
by: Peted | last post by:
i have an mdi application with two child forms Childform A and childform B in a nutshell Childform B has a timer with a routine that polls a ip socket for information every 30sec.
2
by: Amit Dedhia | last post by:
Hi I am developing a scientific application which has moderate level image processing involved. In my application, there is a main application form which invokes another form. When this form...
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.