开发者

TThread.Execute is not called as expected

I am trying to display an activity indicating overlay (a spinning circle of dots) during a lengthy operation in my application. For this, i created a borderless transparent form with a TImage and an Imagelist, which i sought to update in a thread during the time the main thread is busy.

The problem i encountered is that the lengthy operation does not seem to get 'interupted' by my thread. The thread.Execute function loops a few times before the lengthy operation starts, and then again when the operation is finished.

It seems as if the thread is starved for some reason. I tried to raise it's priority, but could not see any effect.开发者_高级运维

Does anyone have similar experiences to share, or maybe even a solution?


Source code of thread function

procedure TIndicatorThread.Execute;
begin
  inherited;
  while(not Terminated) do
    begin
      fDlg.fCurindex := (fDlg.fCurindex+1) mod 12;
      Synchronize(UpdateImage);
      Application.ProcessMessages;
      sleep(80);
    end;
    Synchronize(fDlg.close);
    Synchronize(fDlg.Free);
end;

main thread

begin
[...]
myThread := TIndicatorThread.Create;
mythread.Resume;

Init_SomeUIRelatedstuff;
Application.ProcessMessages;

DoLengthyOperation; 

mythread.Terminate;


Your are doing the bulk of your thread work inside of Synchronize(), which delegates the work back to the main thread. If the main thread's lengthy operation is not processing new messages from the message queue, then Synchronize() has to wait. That is why your thread does not do anything while the lengthy operation is running.

Your code is a poor example of how to use a thread effectively. What you should have done instead is perform the lengthy operation itself in the thread, and let the main thread handle the UI updates while the thread is running, eg:

procedure TWorkThread.Execute; 
begin 
  DoLengthyOperation;  
end; 

begin 
  ...
  Init_SomeUIRelatedstuff; 
  Application.ProcessMessages; 

  myThread := TWorkThread.Create(False);
  while WaitForSingleObject(myThread.Handle, 80) = WAIT_TIMEOUT do
  begin 
    fDlg.fCurindex := (fDlg.fCurindex+1) mod 12; 
    UpdateImage; 
    Application.ProcessMessages; 
  end; 
  mythread.Free;

  fDlg.Close; 
  fDlg.Free;

  ...
end;


I used GIF image component that can show animated GIFs (http://www.tolderlund.eu/delphi/), and I put a lengthy operation inside a timer (which executes in separate thread).

Simple but effective.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜