Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.01.14;
Скачать: [xml.tar.bz2];

Вниз

Помогите разобраться с 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.015 c
15-1166110968
Eraser
2006-12-14 18:42
2007.01.14
Редактор ASCII графики


15-1166388021
partizan
2006-12-17 23:40
2007.01.14
Вписать эллипс макс. площади в 4-угольник


15-1166618176
infom
2006-12-20 15:36
2007.01.14
Есть ли проблемы с AMD Athlon 64 X2 ?


15-1165935162
Гарри Поттер
2006-12-12 17:52
2007.01.14
Монтаж локальной сети. Склько может стоить?


8-1148145044
Efir
2006-05-20 21:10
2007.01.14
Работа с палитрой в Delphi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский