Recent

Author Topic: Problem with Threads  (Read 10020 times)

fredycc

  • Sr. Member
  • ****
  • Posts: 264
Problem with Threads
« on: May 25, 2010, 03:48:18 pm »
Hi again; I have some questions about Threads; my case is: I have a single application, The MainThread and a secondary Thread; The second thread calculate the time each second is like a clock; this have the Synchronize method to help me display the time into my MainForm(MainThread), No problem here, the time is displayed correctly; But sometimes the mainThread try to connect with a db server, sometimes this take 5 seconds; in that time the second thread appear is paused; and start calculated again after connect to database.  :o

I discover that if you don't assign the event that show the time calculated for the second thread; the second thread never paused, and still calculated in that 5 seconds; Thanks  :-\

The Second Thread that calculate the time:

type
  { TMyThread }
  TShowStatusEvent = procedure(textTime: TTime; objStatus: boolean) of Object;
  TMyThread = class(TThread)
  private
    vstsObj: boolean;
    FOnShowStatus: TShowStatusEvent;
    procedure ShowStatus;
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: boolean);
    property OnShowStatus: TShowStatusEvent read FOnShowStatus write FOnShowStatus;
    Time : TTime;
  end;

implementation 

constructor TMyThread.Create(CreateSuspended : boolean);
begin
     FreeOnTerminate := True;
     inherited Create(CreateSuspended);
end;

procedure TMyThread.Execute;
begin

  While (not Terminated) do begin
     Time := Time + 1/86400; //(24 * 60 * 60);
     Synchronize(@Showstatus);
     Sleep(1000)
  end;

end;

procedure TMyThread.ShowStatus;
begin
  if Assigned(FOnShowStatus) then begin
     FOnShowStatus(Time, vstsObj);
  end;
end;

MainThread:

procedure TfrmMainDesk.FormShow(Sender: TObject);
begin
  if MyTime = nil then begin
     MyTime := TMyThread.Create(True);
     MyTime.Time := Now - 30/1440;
     MyTime.OnShowStatus := @ShowTime;
     MyTime.Resume;
  end;
end;

procedure TfrmMainDesk.ShowTime(textTime: TTime; objStatus: boolean);
begin
    Label1.Caption := '[ '+ FormatDateTime('hh:mm:ssampm', textTime) + ' ]';
end;

 

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1891
Re: Problem with Threads
« Reply #1 on: May 25, 2010, 04:02:28 pm »
I have some questions about Threads;

I can't find a question here.

fredycc

  • Sr. Member
  • ****
  • Posts: 264
Re: Problem with Threads
« Reply #2 on: May 25, 2010, 05:14:47 pm »
My question will be; Why the second thread pause while the main thread try to connect with database?, Sorry

If I comment: MyTime.OnShowStatus := @ShowTime in the mainthread the second thread works fine. Of course never show the new time calculated.

mas steindorff

  • Hero Member
  • *****
  • Posts: 500
Re: Problem with Threads
« Reply #3 on: May 25, 2010, 05:24:28 pm »
I think I know what your asking.
why is your time off when it gets displayed?
the Synchronize places a request to be handed in the main codes Que (along with the keyboard, mouse, screen update and any timer or other event generators).  until it gets serviced, it is paused.

what I had to do to get a time is to have the main thread go get the current value of the timer thread when it was ready for it.  that way the sec thread keep on trucking while the OS has Main on hold.  A timer in the main thread that gets the count form the timer thread and displays it is probably what your after.

Code: [Select]
constructor TTimeObj.Create(interval:integer; CreateSuspended: Boolean);
begin
  Inherited Create(CreateSuspended);
  FreeOnTerminate:=TRUE;
  ticks :=0;
  Mydelay := interval;
end; 

procedure TTimeObj.Execute;
begin
  while (not Terminated) do begin
   sleep(Mydelay);
   inc(ticks);
  end;
end; 

function TTimeObj.ShowTimer: UINT64; // to be called from mother
begin
  if not assigned(Self) then exit; // safe code
  result := ticks;
end;
windows 7/10 - laz 2.0 / 1.2.6 general releases

fredycc

  • Sr. Member
  • ****
  • Posts: 264
Re: Problem with Threads
« Reply #4 on: May 25, 2010, 06:58:54 pm »
Excuse me mas steindorff; I need create a timer to get the value of the second thread? and the timer is created in the mainform?; I don't know if it is possible, but to avoid use Synchronize Can I access the value calculated by the second thread since mainthread?, how?  %)

Thanks.

mas steindorff

  • Hero Member
  • *****
  • Posts: 500
Re: Problem with Threads
« Reply #5 on: May 25, 2010, 07:58:41 pm »
the rest of the thread code not shown above:
Code: [Select]
Type

  { TTimeObj }

  TTimeObj = class(TThread)
   Mydelay:integer;
   ticks :UINT64;    // I can acess ticks form outside
//  private
  protected
    procedure Execute; override;
  public
    function ShowTimer: UINT64;
    Constructor Create(interval:integer;CreateSuspended:Boolean);
 //   destructor Destroy; override;
  end;
here is the main code section:

some here I create the Thread with
mytimer := TTimeObj.Create(250,FALSE);   // one tick every 250ms, start running
 
then when I'm ready to check the time
end_time :=myTimer.ticks;  // div by 4 if you need seconds

If you need the screen to be updated at a req interval then drop a Ttimer on your form, set the interval to your update time and then add the code below into the OnTimer event.  this way the thread keep on running even if the OnTimer event is delayed.  

Code: [Select]
procedure TFMain.Timer1Timer(Sender: TObject);
var SecondSoFar :integer;  // or float if sub seconds
begin
  SecondSoFar := MyTimer.ticks div 4;  //
 // then convert ticks -> final output.  for just plan seconds do..
  Label1.Caption := '[ '+ Format('seconds =%d', [SecondSoFar] ) + ' ]'
end;

note:
Accessing the threads "Ticks" variable while it is being update may cause some misque somewhere but I've been using this code off and on for a few mouths without any exceptions fireing off at the 4 ticks/second rate.
 




« Last Edit: May 25, 2010, 08:02:15 pm by mas steindorff »
windows 7/10 - laz 2.0 / 1.2.6 general releases

fredycc

  • Sr. Member
  • ****
  • Posts: 264
Re: Problem with Threads
« Reply #6 on: May 25, 2010, 10:51:46 pm »
Looks interesting mas steindorff I'll test it; :).

Thanks a lot. ;D

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1891
Re: Problem with Threads
« Reply #7 on: May 26, 2010, 03:44:49 am »
I do not completely understand what you need, but if your main thread is "blocked" for 5s connecting to the DB, then the GUI is blocked - period -
So generally it would be better to put your "blocking" code in a separate thread.

fredycc

  • Sr. Member
  • ****
  • Posts: 264
Re: Problem with Threads
« Reply #8 on: May 26, 2010, 09:23:08 am »
Quote
So generally it would be better to put your "blocking" code in a separate thread.

Hi, theo; thanks for ask, thats the reason for the second thread like you say; It's created when I show the Main form, and calculate the time each second (add one second)(I don't want to show the time of the machine); but the second threads is paused when I use synchronize to acces the GUI to display the new time; is like mas steindorff explain:

Quote
the Synchronize places a request to be handed in the main codes Que (along with the keyboard, mouse, screen update and any timer or other event generators).  until it gets serviced, it is paused.

If I ommit synchronize in the second thread, the thread never is paused; but I can't access the GUI to display the time calculated.

I lost that 5 seconds, sometimes more in the calc each time connect to data base.
« Last Edit: May 26, 2010, 09:30:16 am by fredycc »

fredycc

  • Sr. Member
  • ****
  • Posts: 264
Re: Problem with Threads
« Reply #9 on: May 26, 2010, 11:16:00 am »
Thnaks a lot mas steindorff; the code you send me, work great; the Mainform sometimes "blocking" but the thread keep on running.  ;D

mas steindorff

  • Hero Member
  • *****
  • Posts: 500
Re: Problem with Threads
« Reply #10 on: May 26, 2010, 02:26:30 pm »
glad I could help.  Lazarus has a lot of potenal if we all keep working as a team
windows 7/10 - laz 2.0 / 1.2.6 general releases

 

TinyPortal © 2005-2018