Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.01.08;
Скачать: [xml.tar.bz2];




Вниз

Thread: Suspend/Resume & Synchronize 


mitry   (2001-12-15 02:53) [0]

Уважаемые коллеги, помогите пожалуйста, я не спал уже 3 ночи.
Проблема вот в чем:
Если часто приостанавливать(Suspend) и запускать(Resume) поток, который вызыает Synchronize, то при перерисовке окна, программа часто виснет.
Например, если запустить следующую программу и попереключаться между ней и Delphi, то нижеприведенное приложение умолкнет навеки:

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, ComCtrls;

type

TMyThread = class(TThread)
private
procedure Update;
protected
procedure Execute; override;
end;

TMainForm = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
MyThread: TMyThread;
public
{ Public declarations }
end;

var
MainForm: TMainForm;

implementation

{$R *.dfm}

procedure TMyThread.Update;
begin
//
end;

procedure TMyThread.Execute;
begin
repeat
Sleep(100);
Synchronize(Update);
until Terminated;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
MyThread := TMyThread.Create(false);
Timer1.Interval := 1;
Timer1.Enabled := true;
end;

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Timer1.Enabled := false;
if MyThread.Suspended then MyThread.Resume;
MyThread.Terminate;
MyThread.WaitFor;
MyThread.Free;
end;

procedure TMainForm.Timer1Timer(Sender: TObject);
begin
if not MyThread.Suspended then MyThread.Suspend else MyThread.Resume;
end;

Нужно это все вот для чего: я сделал анимированную кнопку: наводишь на нее мышкой - запускается поток, проигрывающий анимацию, убираешь мышку - поток останавливается. Пользователь может возить мышкой довольно часто, поэтому это и приводит к вышеописанной проблеме.
В моей программе нельзя использовать Timer вместо потоков.
Если кто-нибудь подскажет в чем тут дело, я подарю ему свои лучшие компоненты(включая анимированную кнопку). Торжественно клянусь.
Прошу прощения за длинный вопрос, но короче никак нельзя.
Delphi6, Win98.
Спасибо.



paul_shmakov   (2001-12-16 02:06) [1]

использование suspend/resume в данном случае не лучший выход. да и использование потока для каждой кнопки - тоже плохо. но раз нужен поток, тогда почему бы не сделать проще: когда возникает необходимость начать воспроизводить анимацию мы устанавливаем флаг , метод execute проверяет этот флаг, и, если он установлен, выполняет прорисовку анимации. когда курсор с кнопки ушел - сбрасываем этот флаг.
единственное, чтобы не было проблем, флаг нужно менять вызовом одной из Interlocked* функций. например, InterlockedIncrement/InterlockedDecrement.

"Прошу прощения за длинный вопрос, но короче никак нельзя."
все бы вопросы были такими длинными и подробными :)




Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.01.08;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.72 MB
Время: 0.027 c
14-22361          Nikolay               2001-11-08 00:17  2002.01.08  
Да...............................


1-22074           Bb                    2001-12-17 21:28  2002.01.08  
HELP!!!!


1-22150           Dimich                2001-12-20 13:22  2002.01.08  
Как сделать прокрутку в Panel


1-22245           T2                    2001-12-16 07:12  2002.01.08  
Gost & best crypt


3-21908           Dup                   2001-11-28 13:27  2002.01.08  
Зависание приложения