Текущий архив: 2007.01.14;
Скачать: CL | DM;
Вниз
Помогите разобраться с TThread Найти похожие ветки
← →
allrussia © (2006-12-24 06:16) [0]Пытаюсь использовать пример по TTread
мне нужно, чтобы во время выполнения цикла форма не "висла", т.е. отвечала на нажатия и т.дtype
TMyThread = class(TThread)
private
{ Private declarations }
protected
procedure DoWork;
procedure Execute; override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TMyThread.Execute;
begin
Synchronize(DoWork);
end;
procedure TMyThread.DoWork;
var i: integer;
begin
for i:=0 to maxint do
Form1.Caption:=inttostr(i);
end;
procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
begin
for i:=0 to maxint do
Form1.Caption:=inttostr(i);
end;
procedure TForm1.Button2Click(Sender: TObject);
VAR t1: TMyThread;
begin
t1:=TMyThread.Create(False);
t1.Priority:=tpIdle;
end;
а то получается что и в случае с Button1 и Button2 форма упорно виснет
Где ошибка?
это просто пример, в потоке может быть любая функция
например CopyFile(10GB)
← →
Palladin © (2006-12-24 08:07) [1]Кто тобе рессказал про Synchronize?
← →
allrussia © (2006-12-24 10:06) [2]из примера
Производя любое обращение к объекту VCL из потока, убедитесь, что при этом используется метод Synchronize; в противном случае результаты могут оказаться непредсказуемыми.
попробовал простоprocedure TMyThread.Execute;
begin
DoWork;
end;
не меняется вообще кэпшн у формы, пустым становится
и непонятно как отловить завершение потокаprocedure TForm1.Button2Click(Sender: TObject);
begin
t1:=TMyThread.Create(False);
t1.Priority:=tpIdle;
ShowMessage ("Completed!")
end;
Сообщение о завершении почему-то сразу вылетает
пробовалprocedure TForm1.Button2Click(Sender: TObject);
begin
t1:=TMyThread.Create(False);
t1.Priority:=tpIdle;
WaitForSingleObject (t1.handle, INFINITE)
ShowMessage ("Completed!")
end;
опять форма виснет... :(
← →
Virgo_Style © (2006-12-24 11:15) [3]при завершении потока, afair, TThread.OnTerminate вызывается...
а по поводу "зависания" формы - а что ты хочешь, в первом случае постоянный (sic!) synchronize, а во втором - просто ожидание.
Вот попробуй, например, сделать в потоке цикл + sleep(10), а synchronize делать только(!) для работы с объектами VCL.
← →
Anatoly Podgoretsky © (2006-12-24 11:53) [4]> Palladin (24.12.2006 8:07:01) [1]
> Кто тобе рессказал про Synchronize?
Архангельский
← →
allrussia © (2006-12-24 12:15) [5]Virgo_Style
Я бы хотел найти готовое решение мне нужно наподобие следующего
procedure TForm1.tatata;
begin
DisableControls;
StartThread; // поток
Showmessage ("AllDone");
EnableControls;
end;
мне нужно чтобы форма не тормозила + дождаться его завершения
конечно я могу в сам поток добавить Showmessage и Disable/EnableControls
но существует ситуация, если процедура потока завершится некоректно
то контролы на форме будут недоступны и придется рестартовать приложение
также я могу добавить после StartThread
while not EndThread do Application.ProcessMessages;
а в конец потока EndThread:=true;
но это ресурсоемко, а поток и так жрет "много"
а sleep я добавил в поток - ничего не изменилось, также сообщение сразу вылетает
← →
tesseract © (2006-12-24 12:34) [6]
> Anatoly Podgoretsky © (24.12.06 11:53) [4]
> > Palladin (24.12.2006 8:07:01) [1]> Кто тобе рессказал
> про Synchronize?Архангельский
Запинали бедного преподавателя просто :-)
Вообще я считаю наименее глючное использование потокоы - сообщения + критические секции. поток послал сообщение - главный поток выдрал данные из крит секции. Поток в таком случае должен перехватывать сообщение на завершение операций.
Только,вот, зачастую у меня чего-то память течет.........
← →
Virgo_Style © (2006-12-24 12:36) [7]allrussia © (24.12.06 12:15) [5]
Еще раз.... Читать медленно, по слогам, при этом думать над прочитанным:
При завершении потока вызывается TThread.OnTerminate.
чтобы форма не зависала, следует тяжелые действия выполнять в потоке без Synchronize, а в Synchronize только работать с интерфейсом. У тебя в примере [0] работа с ним идет постоянно, вот он и подвисает.
А если
allrussia © (24.12.06 12:15) [5]
Я бы хотел найти готовое решение
то ищи, не смею задерживать, удачи в поисках, попутного ветра.
← →
Anatoly Podgoretsky © (2006-12-24 13:06) [8]> tesseract (24.12.2006 12:34:06) [6]
Ну если бы его дело не цвело и процветало, кому бы он нужен был.
← →
allrussia © (2006-12-24 13:18) [9]tesseract
сообщения + критические секции.
не подскажете самый примитивный пример?
упростим задачу: мне не нужно взаимодействовать с интерфейсом.
поток допустим посто копирует файл CopyFile ("1", "2", false);
нужна вот такая схемаprocedure TForm1.tatata;
var t: TMyThread;
begin
t:=TMyThread.Create(False);
Showmessage ("AllDone");
end;
а не такая:procedure TMyThread.Execute;
begin
CopyFile (...);
showMessage ("AllDone");
end;
и не такаяTMyThread.OnTerminate (...);
begin
showMessage ("AllDone");
end;
Virgo_Style
При завершении потока вызывается TThread.OnTerminate.
ну вызывается ну и что, сообщение то уже давно вылетело, когда вы нажали на кнопку, но этот вариант безусловно хороший, возможно если ничего не найду буду использовать его
чтобы форма не зависала, следует тяжелые действия выполнять в потоке без Synchronize, а в Synchronize только работать с интерфейсом.
ок, это я уже экспериментально понял, но...
примерчик бы от вас самый простой
что в [0] надо изменить, чтобы caption у формы обновлялся в потоке и форма не висла, не обязательно ждать завершения потока
а то какя уже писал
попробовал просто
procedure TMyThread.Execute;
begin
DoWork;
end;
не меняется вообще кэпшн у формы, пустым становится
← →
MetalFan © (2006-12-24 13:20) [10]
> procedure TForm1.tatata;
> begin
> DisableControls;
> StartThread; // поток
> Showmessage ("AllDone");
> EnableControls;
> end;
>
> мне нужно чтобы форма не тормозила + дождаться его завершения
> конечно я могу в сам поток добавить Showmessage и Disable/EnableControls
>
> но существует ситуация, если процедура потока завершится
> некоректно
> то контролы на форме будут недоступны и придется рестартовать
> приложениеDisableControls;
?
try
StartThread; // поток
Showmessage ("AllDone");
finally
EnableControls;
end;
← →
allrussia © (2006-12-24 13:27) [11]MetalFan
увы, это первое и неуспешное что я попробовал, прежде чем сюда писать
← →
sniknik © (2006-12-24 13:48) [12]
> DisableControls;
> try
> StartThread; // поток
> Showmessage ("AllDone");
> finally
> EnableControls;
> end;
работа с базой, судя по Disable/EnableControls? и в потоке действия над данными?
и что вы тут делаете? поток же параллельно выполняется, т.е. если сделан правильно то старт потока StartThread начнется и тутже закончится, хотя сам он еще полчаса может выполняться, т.е. уже и сообщение покажет про "AllDone" и контролы откроет, а еще не выполнится, только начнет.
а ты меняешь данные в рекортсетах которые привязаны к контролам на форме (понадобилось DisableControls) изменения в них потянут изменения в контролах... (т.к. EnableControls выполнится сразу после старта потока) чего делать нельзя без синхронизации...
бред пытаешься запрограммировать короче.
логику надо пересматривать.
← →
allrussia © (2006-12-24 13:58) [13]sniknik
работа с базой, судя по Disable/EnableControls? и в потоке действия над данными?
Disable/EnableControls? - это "левые" процедуры которые выключают некоторые кнопки, пункты меню и прочее, не относящиеся к Dataset
в потоке выполняется "тяжелая" функция по работе с файлами > 1GB
действия над данными базы действительно есть, но этого можно избежать
сейчас задача упрощена в потоке выполняется только действие со сторонними файлами
← →
Virgo_Style © (2006-12-24 14:51) [14]allrussia © (24.12.06 13:18) [9]
ну вызывается ну и что, сообщение то уже давно вылетело, когда вы нажали на кнопку
Ты сообщение сам выводишь, или оно вылетает аж не поймаешь и убивает наповал?
Ты уж реши, то ли тебе живой интерфейс нужен, то ли ожидание, пока поток выполнится (что смысл существования этого потока сводит к нулю).
allrussia © (24.12.06 13:18) [9]
примерчик бы от вас самый простой
DoWork:for i:=0 to MaxInt do begin
Sleep(100); //имитация бурной деятельности
Synchronize(DoShow);
end;
DoShow:
Form1.Caption:=inttostr(i);
Вызов DoWork без Synchronize, конечно.
← →
allrussia © (2006-12-24 15:01) [15]Ты уж реши, то ли тебе живой интерфейс нужен, то ли ожидание, пока поток выполнится (что смысл существования этого потока сводит к нулю).
смысл потока - чтобы форма не зависала на время выполнения процедуры
а ожидание завершения нужно чтобы команды процедуры выполнялись в определенном порядке
т.е. поток выполняет роль обычной команды в процедуре
...
типа for i:=0 to maxint do begin }
inttostr(i) } вместо этого поток
Application.processmessages }
Showmessage ("great")
... и т.д.
еще раз повторюсь это так пример на самом деле там операции с большими файлами
но безусловно надо пересмотреть проектирование этой процедуры, т.к. понимаю что кривизна это все
Страницы: 1 вся ветка
Текущий архив: 2007.01.14;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.011 c