Search code examples
multithreadingdelphiindy

Loop property of TidThreadComponent


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.


Solution

  • 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.