12

How can I wait for a variable to change in a thread? For example I want to wait for a number to change. So instead of using Sleep() what else is there?

while SomeVariable > 0 do
Sleep(1);
user3655788
  • 135
  • 1
  • 10
  • Too broad question, you should define it more precisely. – rsrx May 20 '14 at 22:00
  • 7
    @Marko: It's not an overly-broad question. "How to know when a value changes in another thread without having to Sleep in a loop" is a pretty specific question that's easy to answer if you've got experience with multithreading. – Mason Wheeler May 20 '14 at 22:01
  • 2
    @Mason, why in the world are you talking about something like `const` and a setter (?) in your answer ? Why have you mentioned event in just a small paragraph ? Event itself is the most important thing there, isn't it ? I'm wondering what the people here vote for and it's really time for me to quit... – TLama May 20 '14 at 23:17
  • 1
    @TLama: The setter makes sure that the Event gets set when the value changes, and the `const` trick makes sure that the compiler tells you everywhere you need to change an assignment into a function call. Can you think of any way to have confidence that **the event will be set when the value changes,** which is what the OP asked for, without doing this? – Mason Wheeler May 20 '14 at 23:20
  • @TLama: Besides, if I say "just use a `TSimpleEvent`," that might solve this issue, but that's it. But if I explain principles like encapsulation and TCIYF, that might help someone actually become a better developer. :) – Mason Wheeler May 20 '14 at 23:31
  • 2
    @TLama: it is like the old saying: "if you give a man a fish [use X to solve a Y problem now], he will eat for a day; teach a man to fish [learn how concept Y works] and he will eat for a lifetime [solve Y-related problems whenever they appear]" :) – Remy Lebeau May 21 '14 at 00:43
  • @MasonWheeler I agree that using `TEvents` is a nice and great idea. However it is afterall synchronization and using too many of them in the thread will affect performance. – user3655788 May 21 '14 at 05:57
  • 1
    If you give a man a fish, he will eat for a day. If you teach a man how to fish, he will understand why some think golf is exciting. – Rudy Velthuis May 21 '14 at 06:28
  • @Rudy, golf is a game you can experience but never master. Give a man a ball and a driver and he will spend the rest of his life trying to hit the ball farther and straiter. – LU RD May 21 '14 at 06:51
  • @RudyVelthuis I hear dentists are big in to golf. :) – user3655788 May 21 '14 at 06:55
  • 1
    @user3655788: But not this dentist. I think it is time to stop wasting this forum with chit-chat. I know I started it, but I could not resist. – Rudy Velthuis May 21 '14 at 07:46
  • @Mason, I agree with your idea. Having property for this is the best you can do, I think. However, I think that *"such as having it set the signal of a `TSimpleEvent`"* is quite little about the main point of this question. And to check whether the value has changed in the setter is a must to meet the requirement, so there is no *"if you want to be more sophisticated"*. Also, it would be fine to wrap that waiting into a method like e.g. `WaitForSomeVariableChange` to avoid publishing of that event, which is missing in your post. The note about event reset. Why not to use autoreset event then ? – TLama May 21 '14 at 08:51
  • @TLama Good point. How can it be done? `TEvent` is too bloated for what I need. – user3655788 May 21 '14 at 08:57
  • @user3655788, err, how can be done what ? Btw. `TEvent` or `TSimpleEvent` is not bloated for your task. – TLama May 21 '14 at 12:51
  • @TLama Its not a one liner. – user3655788 May 21 '14 at 13:04

1 Answers1

19

If you want to be notified when something changes, a bit of encapsulation can be your friend.

If SomeVariable is a variable and not a property, change its declaration to const. This will break all code that writes to it. That's a good thing; the compiler finds it for you instead of you having to search for it. Then create a procedure called SetSomeVariable (leave it blank for the moment) and change the broken code to call this instead. When everything will compile, change SomeVariable back to a variable, implement the setter routine, and if possible, encapsulate SomeVariable so nothing will be able to set its value directly without calling the new function. (If it's a property, you can do this all much more simply by declaring a setter.)

Once you have a function that sets its value, you can introduce new effects into the process, such as having it set the signal of a TSimpleEvent. (Or, if you want to be more sophisticated, have it set the signal if the new value <> the old value.)

Instead of sleeping, have your code WaitFor the event. Remember to reset it afterwards!

Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477
  • 6
    [`TCountdownEvent`](http://docwiki.embarcadero.com/CodeExamples/en/TCountdownEvent_(Delphi)) is a handy synchronizing object that is signaled when the count is zero. – LU RD May 20 '14 at 22:19