Главная страница
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.028 c
2-1143812478
SilentDon
2006-03-31 17:41
2006.04.16
Ошибка при вызове SetLength применительно к динамическим массивам


2-1143624495
pkm
2006-03-29 13:28
2006.04.16
Просмотр фалов в папке.


2-1143642908
Chapchaps
2006-03-29 18:35
2006.04.16
Помогите, пожалуйста!


15-1143185711
Александр Иванов
2006-03-24 10:35
2006.04.16
Майкрософт действует методами Гербалайфа?


15-1142841744
Layner
2006-03-20 11:02
2006.04.16
Прослушал тут курсы C#...