0

I have a (hopefully) simple question:

What is the meaning of Loop property of TidThreadComponent?

My program with threads works well when compiled in Delphi 7, but threads works unpredictable when compiled under Delphi Embarcadero. I suspect Loop property of TidThreadComponent (don't remember it in Delphi 7).

The name Loop says that Loop=true should make he thread to start in the loop until terminated manually. However, something else is observed.

Thanks in advance for any idea.

Ken White
  • 123,280
  • 14
  • 225
  • 444
Spectorsky
  • 608
  • 4
  • 23
  • 2
    What is "Delphi Embarcadero"? Embarcadero is the name of the company that owns Delphi these days, it is not the name of a Delphi version. It would be helpful if you added the actual version of Delphi you are using (such as Delphi 2009, or Delphi XE7, or Delphi 10.3, or ...). – Andreas Rejbrand Sep 25 '19 at 10:45
  • It would also help if (in addition to the actual Delphi version) you indicated the version of Indy that you're using. – Ken White Sep 25 '19 at 12:26
  • 1
    The source code for `TIdThread` shows the use of `Loop`. If it's True (the default) then the code executes a `while not Stopped do` loop that calls `Run` repeatedly. As you've not provided code, it's impossible to tell you why *something else is observed*. – Ken White Sep 25 '19 at 12:31
  • Thanks to everybody who answer. Version of IDE is Embarcadero® Delphi 10.3 Version 26.0.33219.4899. I don't involve Indy (at least, explicitly). I could provide the code, but it is more than hundred lines, and there is a problem to make a little example (each of the line might be essential for the question). When `loop` is `true`, indeed `run` method repeats (`before` and `after` perform once). However, when `loop` is `false`, all these three methods repeat until being terminated. – Spectorsky Sep 25 '19 at 16:08
  • 1
    Your code does explicitly involve Indy, because `TIdThreadComponent` is an Indy component, which wraps `TIdThread`. – Ken White Sep 25 '19 at 18:16

1 Answers1

2

Per the documentation of TIdThread, which TIdThreadComponent wraps:

Loop is a Boolean property used to indicate if the Run method for the thread instance is called in a loop.

When Loop contains True (the default value assigned in Create), the Run method will be continuously executed until Stopped returns True.

When Loop contains False, the Run method is called once during execution of the thread.

You ask if Loop=true should make the thread "start in the loop until terminated manually", but it is more accurate to say that the thread's Run() method is looped until the thread is stopped, not terminated. Two different concepts in Indy. A thread can be stopped without being terminated, this allows the thread to be restarted. For instance, when using TIdSchedulerOfThreadPool.

When a TIdThread is stopped, it stops calling its Run() method and will then either Terminate() or Suspend() itself, depending on its StopMode property. The default is smTerminate.

TIdThreadComponent runs an internal TIdThread/Ex, which is derived from TThread. And like most uses of Delphi threads, the thread's Execute() method runs a while not Terminated loop. Inside that Terminated loop, the thread's Loop property controls whether the thread's Run() method is called once per loop iteration, or is called in its own while not Stopped loop per iteration. In other words, it is the difference between this:

while not Terminated do
begin
  if Stopped then
  begin
    if Terminated then Break;
    Suspend;
    if Terminated then Break;
  end;
  BeforeRun;
  Run; // <-- Loop=false
  AfterRun;
end;

And this:

while not Terminated do
begin
  if Stopped then
  begin
    if Terminated then Break;
    Suspend;
    if Terminated then Break;
  end;
  BeforeRun;
  while not Stopped do Run; // <-- Loop=true
  AfterRun;
end;

So, what it basically just boils down to is that Loop controls how many times Run() is called in between BeforeRun() and AfterRun(), nothing more. The thread will keep calling Run() nonetheless until the thread is either stopped or terminated.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770