Форум: "Основная";
Поиск по всему сайту: 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.03 c
1-22131           Катя                  2001-12-20 08:27  2002.01.08  
мне очень надо


4-22513           Oxy2                  2001-10-23 23:23  2002.01.08  
Как создавать формы с разными контролами на чистом API?


14-22353          Merlin                2001-11-02 10:13  2002.01.08  
Я в шоке


14-22335          Сергей1               2001-11-05 21:44  2002.01.08  
ввод символов


3-21920           Alex2                 2001-12-04 15:14  2002.01.08  
Ошибка при завершении