Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behaviour of function Sleep() used in repeat until in Delphi

I have function which is reaction on button click. When I click on the button it should start repeat and write values form an array and show them in labels on main form. Problem is with function sleep - there is some bug or something, cause when I click on the button it waits quite a long time and then it finaly start the action but very quickly. Let's look at my code. Thx for advices.

procedure TForm1.ButtonMereniClick(Sender: TObject);
var
  iterator: Integer;
begin      
  iterator := 1;
  repeat       
    //write some values stored int arrays to labels on form
    LabelTeplota.Caption:='Teplota: '+FloatToStr(poleTeplota[iterator]);
    LabelVlhkost.Caption:='Vlhkost: '+FloatToStr(poleVlhkost[iterator]);
    LabelTlak.Caption:='Atmosférický tlak: '+FloatToStr(poleTlak[iterator]);
    LabelRychlost.Caption:='Rychlost větru: '+FloatToStr(poleRychlost[iterator]);
    LabelRychlost.Caption:='Rychlost větru: '+FloatToStr(poleRychlost[iterator]);
    LabelIterator.Caption:='iterator: '+IntToStr(iterator);
    Sleep(500);//should be 5000 
    Inc(iterator);
  until iterator = 20;
end;
like image 253
user1097772 Avatar asked Mar 11 '12 14:03

user1097772


2 Answers

Don't use Sleep function in GUI thread because you are blocking normal message processing and your application behaves strangely.

It is not clear why you use Sleep in your code. Probably you should update labels from OnTimer event handler of TTimer component instead of using a loop.

like image 83
kludg Avatar answered Nov 15 '22 09:11

kludg


I used two timers to update "slowly" some values (so that the user can see the progress) without slowing down the application or, in the worst case, the system.

//  "weights" for old and new value; I was working on integers
var
  Wa: integer =  1;
  Wb: integer =  9;
  Wt: integer = 10;

//  interval of 1000 ms, of course
procedure frmMain.T1000Timer(Sender: TObject);
begin
  Wa:= 1;
  nValue:= calculate_new_value;
end;

//  100 ms interval
procedure frmMain.T100Timer(Sender: TObject);
begin
  Wb:= Wt -Wa;
  //  displayed value, ie gauge.progress, or something.Value, etc.
  sam.Value:= Round( (Wb *sam.Value +Wa *nValue) /Wt );
  if Wa < Wt then Inc(Wa);
end;
like image 23
Nanni Avatar answered Nov 15 '22 10:11

Nanni