TThread.Execute не вызывается должным образом - PullRequest
1 голос
/ 02 сентября 2010

Я пытаюсь отобразить активность, указывающую наложение (вращающийся круг точек) во время длительной операции в моем приложении.Для этого я создал прозрачную форму без полей с TImage и Imagelist, которые я пытался обновить в потоке в то время, когда основной поток занят.

Проблема, с которой я столкнулся, заключается в том, что длительная операция непохоже, меня "перебивают" мои темы.Функция thread.Execute зацикливается несколько раз, прежде чем начинается длительная операция, а затем снова, когда операция завершается.

Кажется, что поток по какой-то причине истощен.Я пытался поднять его приоритет, но не смог увидеть никакого эффекта.

Есть ли у кого-нибудь похожий опыт, которым можно поделиться, или, может быть, даже решение?


Исходный код потокафункция

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;

основная резьба

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

Init_SomeUIRelatedstuff;
Application.ProcessMessages;

DoLengthyOperation; 

mythread.Terminate;

Ответы [ 2 ]

3 голосов
/ 03 сентября 2010

Вы выполняете большую часть работы с потоками внутри Synchronize (), которая делегирует работу обратно основному потоку.Если длительная операция основного потока не обрабатывает новые сообщения из очереди сообщений, тогда Synchronize () должен ждать.Вот почему ваш поток ничего не делает во время выполнения длительной операции.

Ваш код является плохим примером того, как эффективно использовать поток.Вместо этого вы должны выполнить саму длинную операцию в потоке и позволить основному потоку обрабатывать обновления пользовательского интерфейса во время выполнения потока, например:

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;
2 голосов
/ 09 сентября 2010

Я использовал компонент изображения GIF, который может отображать анимированные GIF (http://www.tolderlund.eu/delphi/),), и я поместил длительную операцию в таймер (который выполняется в отдельном потоке).

Простой, но эффективный.

...