Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.04.16;
Скачать: CL | DM;

Вниз

Проблема с нитью   Найти похожие ветки 

 
thread   (2006-04-04 07:33) [0]

Раньше с нитями толком не работал. Сейчас столкнулся со странной проблемой. Приведенная ниже реализация нити жутко ступорится и крайне медленно работает, подвешивая всю машину.

Вначале был вариант:

 for i:=i to gContacts.Count-1 do
 begin
ADOModule.GetAddressForContact("Контакты",gContacts[i],Street,House);
  frmMain.AddAddress(Street,House,"",0);
 end;

Но по ряду причин, потребовалась его реализация в виде отдельной нити, чтобы не "умервщлять" GUI :)

// описание нити
TLightThread = class(TThread)
private
 ThrI,ThrF,ThrE: Integer;
 procedure ThreadLightMethod;
public
 procedure Execute; override;
end;

[...]

// создание нити
if MassSelect then
begin
 LightThread:=TLightThread.Create(True);
 LightThread.ThrF:=i;
 LightThread.ThrE:=gContacts.Count-1;
 LightThread.FreeOnTerminate:=True;
 LightThread.Resume;
end;

[...]

{ TLightThread }

procedure TLightThread.ThreadLightMethod;
var
Street,House: String;
begin
// запрос к БД
ADOModule.GetAddressForContact("Контакты",gContacts[ThrI],Street,House);
// ряд операций над GUI
frmMain.AddAddress(Street,House,"",0);
end;

procedure TLightThread.Execute;
var
i: Integer;
begin
for i:=ThrF to ThrE do
begin
 ThrI:=i;
 Synchronize(ThreadLightMethod);
end;
end;

Кто может сказать в чем тут трабла? ( Трейсил - все в принципе нормально, но НЕРЕАЛЬНО долго... по сравнению с обычным (без нити) вариантом...


 
balepa ©   (2006-04-04 07:37) [1]

for i:=i to gContacts.Count-1 do
begin
ADOModule.GetAddressForContact("Контакты",gContacts[i],Street,House);
 frmMain.AddAddress(Street,House,"",0);
 Application.ProcessMessage; //и не мучайся
end;


 
thread   (2006-04-04 07:38) [2]

:) это крайний вариант =)

по поводу потока не скажите ничего?


 
balepa ©   (2006-04-04 07:40) [3]

ADOModule.GetAddressForContact("Контакты",gContacts[ThrI],Street,House);
// ряд операций над GUI
frmMain.AddAddress(Street,House,"",0);
Наверное из за этого

Description

Synchronize causes the call specified by Method to be executed using the main thread, thereby avoiding multi-thread conflicts. If you are unsure whether a method call is thread-safe, call it from within the Synchronize method to ensure that it executes in the main thread.

Execution of the thread current is suspended while Method executes in the main thread.


 
MBo ©   (2006-04-04 07:41) [4]

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


 
balepa ©   (2006-04-04 07:41) [5]


> thread   (04.04.06 07:38) [2]
> :) это крайний вариант =)

Почему крайний то?
Я считаю в вашем случае крайний вариант работать с потоком.


 
thread   (2006-04-04 07:43) [6]

MBo -> вынести в поток, ты имеешь в виду?


 
MBo ©   (2006-04-04 07:49) [7]

Execute:

ThrI:=ThrF
цикл пока not Terminated или ThrI<=ThrE
 Запрос;
 Synchronize(Метод,только общающийся с главной формой );
 Inc(ThrI)
конец;


 
balepa ©   (2006-04-04 07:51) [8]

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


 
thread   (2006-04-04 07:53) [9]

procedure TLightThread.Execute;
var
i: Integer;
Street,House: String;
begin
for i:=ThrF to ThrE do
begin
 ThrI:=i;
 ADOModule.GetAddressForContact("Контакты",gContacts[ThrI],Street,House);
 Synchronize(ThreadLightMethod);
end;
end;

и действительно, после переноса запросов к БД в нить, ситуация изменилась в лучшую сторону. Но почему-то не происходит обновления GUI в Synchronize() :(

ладно, буду разбираться. всем спасибо!


 
balepa ©   (2006-04-04 07:59) [10]


> thread   (04.04.06 07:53) [9]
> procedure TLightThread.Execute;
> var
> i: Integer;
> Street,House: String;
> begin
> for i:=ThrF to ThrE do
> begin
>  ThrI:=i;
>  ADOModule.GetAddressForContact("Контакты",gContacts[ThrI],
> Street,House);
>  Synchronize(ThreadLightMethod);
> end;
> end;
>
> и действительно, после переноса запросов к БД в нить, ситуация
> изменилась в лучшую сторону. Но почему-то не происходит
> обновления GUI в Synchronize() :(
>
> ладно, буду разбираться. всем спасибо!

Наверно Потому что раньше было все в куче (var i: Integer; Street,House: Stringing;), а теперь в разных процедурах (потоках) или где у тебя там.



Страницы: 1 вся ветка

Текущий архив: 2006.04.16;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.043 c
2-1143639894
qqpp
2006-03-29 17:44
2006.04.16
Есть не большой вопрос


1-1142427273
DelphiLexx
2006-03-15 15:54
2006.04.16
Отобразить Hint в нужном месте окна


2-1143709295
dera
2006-03-30 13:01
2006.04.16
Как "угадать" разрешение экрана пользователя


15-1143572066
QuickFinder
2006-03-28 22:54
2006.04.16
Delphi5 for Windows x64


2-1144195857
TimScorp
2006-04-05 04:10
2006.04.16
FreeReport 2.32