Форум: "Система";
Текущий архив: 2002.09.05;
Скачать: [xml.tar.bz2];
Внизтреды Найти похожие ветки
← →
roman_tutov (2002-06-22 11:48) [0]пытаюсь программку разбить на треды
В тред вынес процедуры соединения с базой , а в основной
форме сручу бессмысленную анимацию .
Так вот при запуске этого хозяйства код в треде отрабатывает правильно , анимация на главной фовме тоже крутиться ,
но ни одну кнопочку / ползуночек я нажать не могу
и программа перерисовывает только анимацию а на все остильное кладет .
Почему ?
← →
Юрий Зотов (2002-06-22 12:38) [1]Как можно ответить на такой вопрос, не видя кода? Только предположительно.
Вот я и предполагаю, что цикл перерисовки анимации у Вас сделан ручками и гробит все время CPU, выделяемое основному потоку. Вставьте в него Application.ProcessMessages. Или используйте компонент TAnimation.
← →
roman_tutov (2002-06-22 13:15) [2]именно этот компонент и использую. А код приводить - это ну очень много страничек будет.
← →
Юрий Зотов (2002-06-22 13:48) [3]Только что воспроизвел у себя Вашу схему (стандартная анимация CopyFile, второй поток крутил бесконечный цикл бессмысленных вычислений). Никаких проблем, все прекрасно нажимается и т.д.
Приоритет дополнительного потока не повышали? Если повышали, причина может быть в этом.
← →
Tutov Roman (2002-06-24 13:08) [4]я попробую воспроизвести фрагмент кода .
Анимацию я видимо зря приплел .Как я заметил основная форма (котрая породила тред) замораживается на время выполнения треда .
unit Tread1;
interface
uses
Classes;
type
TMyThread = class(TThread)
private
{ Private declarations }
protected
procedure DoWork;
procedure Execute; override;
end;
implementation
uses klient;
procedure TMyThread.Execute;
begin
Synchronize(DoWork);
end;
procedure TMyThread.DoWork;
begin
{Здесь весь мой код}
end;
end.
А далее как я этот тред запускаю .
T1 := TMyThread.Create(False);
Где собака порылась ?
← →
MBo (2002-06-24 13:24) [5]Понятно, непрерывное обращение к главному потоку все замораживает.
стоит сделать так
procedure TMyThread.Execute;
begin
while not Terminated do begin
/// здесь делать работу, не требующую синхронизации
Synchronize(DoWork);
end;
procedure TMyThread.DoWork;
begin
//Здесь МИНИМУМ - только взаимодействие с VCL
end;
end.
← →
Tutov Roman (2002-06-24 13:57) [6]Что значит не требующее синхронизации ? С чем синхронизироваться нужно ? И главноне зачем. Может статья толковая где есть ?
Кстати я попробовал сделать как выше написано ,глюки полезли странные ,Тот код что сам по себе нормально работал , стал
подглючивать . То таблицу не увидели , то еще чего ...
← →
Tutov Roman (2002-06-24 14:01) [7]Что есть VCL
← →
MBo (2002-06-24 14:13) [8]краткая статья есть на этом сайте, в разделе Статьи, конечно.
В поставке Delphi есть отличный пример
>С чем синхронизироваться нужно
Взаимодействие с компонентами главного потока.
Пример - доп. поток скачивает информацию из Инета, по окончанию
скачки обрабатывает принятые данные, и с помощью Synchronize передает выжимку (небольшой объем) в Memo на форме. Во время выполнения метода, запущенного с помощбю Synchronize, главный поток ждет, не выполняя никаких действий, по окончанию возобновляет свою работу.
В твоей задаче, если действие разовое, можно убрать
while not Terminated do begin,
а если нет, то можно при необходимости останавливать поток из него самого.
← →
Tutov Roman (2002-06-24 14:31) [9]У меня разовое действие. Фактически мне нужно породить нитку ,
Нитка должна отработать 1 раз и далее она больше не нужна...
Получается что Synchronize передает выжимку работы процедуры
procedure TMyThread.DoWork . А если код отработал в процедуре
procedure TMyThread.Execute ? Synchronize и оттуда выжимку вытянет ?
← →
MBo (2002-06-24 14:48) [10]не совсем так. Synchronize ничего не вытягивает -просто обеспечивает безопасное взаимодействие.
Делай всю долгую работу в Execute (или вызывай из нее еще один метод Thread-a), а в DoWork передавай результаты
← →
Tutov Roman (2002-06-24 14:57) [11]Так я совсем запутался...:( Зачем мне в DoWork передовать результат ? Какой код должен быть в DoWork. Т.е что он должен выполнять ?
Зы А как из треда этот самый тред закрыть ?
← →
Игорь Шевченко (2002-06-24 14:59) [12]Synchronize заставляет код, указанный в процедуре-аргументе, выполняться в основном потоке, а не в вашем. Тем самым, вы отключаете параллельную работу вашего потока.
← →
Lord Warlock (2002-06-24 15:03) [13]Про Synchronize - это метод блокирует компоненты, к которым идет обращение из функции, указанной как параметр (в данном случае DoWork). Отличается повышенной тормознутостью но необходим для компонентов, у которых нем методов блокировки (Look, UnLook) для того, чтобы при назаначении им скажем Text или Caption на экране не выводилось невесть чего. Т.е. заблокитровали контрол, чего-то ему назначили в функции, разблокировали. Во время блокировки не происходит перерисовывания контрола, и он недоступен. В принципе можно не использовать Synchronize, но тогда могут появиться глюки.
Если ты не изменяешь визуальных контролов в своей функции, Syncronize не нужно в принципе
← →
Romkin (2002-06-24 15:04) [14]Поток предназначен для работы асинхронно с остальными потоками. Вызов Syncronize обеспечивает выполнение метода, передаваемого в него, синхронно с основным потоком. Результат тот же, как если DoWork выполнялся в основном потоке. Синхронизация обычно нужна для визуализации.
В вашем случае в execute потока необходимо создавать все объекты соединения с базой, выполнять работу и затем уничтожать их. В этом случае объекты будут принадлежать потоку, и синхронизация не нужна.
← →
MBo (2002-06-24 15:07) [15]примерчик
procedure TinetThread.Execute;
begin
DoWork;
end;
procedure TinetThread.DoWork;
begin
inet:=tnmhttp.create(nil);
try
inet.Get(" http://www.xxxx.yyy.com");
s:=inet.body;
if pos("Status",s)>0 then delete(s,1,pos("Status",s)+5);
...длинная работа со строкой S
except
end;
inet.free;
Synchronize(updatesbar);
end;
procedure tinetthread.updateSBar;
begin
form1.sbar.Panels[10].Text:=s;
end;
← →
Tutov Roman (2002-06-24 15:09) [16]Так . Подключени к базе должно тогда выглядеть таким образом ?
Отключили DbGrid Запустили тред подключились к базе (в треде)
а затем после отработки треда включили DbGrid ? Или я опять не про то ?
ЗЫ. Именно по этому валятся в кору все обработчики OnGetText ?
← →
Romkin (2002-06-24 15:11) [17]У потока должно быть свое подключение к базе (если через BDE - то своя TSession). И создаваться компоненты доступап должны в методе Execute. Если нужна визуализация - форма тоже должна создаваться в этом методе
← →
Lord Warlock (2002-06-24 15:15) [18]
> Отключили DbGrid Запустили тред подключились к базе (в треде)
> а затем после отработки треда включили DbGrid
что-то в этом роде...
> валятся в кору все обработчики OnGetText
на время соединения и их отключай
← →
Tutov Roman (2002-06-24 15:18) [19]Хм...получается такой код не допустим ?
procedure TMyThread.Execute;
begin
Form1.pFIBDatabase1.Connected:=true;
Form1.pFIBDataset1.Active:=true;
Form1.pFIBDataset2.Active:=true;
Form1.pFIBDataSet3.Active:=true;
end;
procedure TMyThread.DoWork;
begin
{совсЭм пусто}
end;
end.
И на pFIBDatabase1 к базе не цапанется ?
← →
Игорь Шевченко (2002-06-24 15:26) [20]RTFM, RTFM и еще раз RTFM
← →
Tutov Roman (2002-06-24 15:28) [21]А как на время соединения отключить обработчик OnGetText ?
← →
Lord Warlock (2002-06-24 15:34) [22]
> procedure TMyThread.Execute;
> begin
> Form1.pFIBDatabase1.Connected:=true; <-Ошибка будеть здесь
> Form1.pFIBDataset1.Active:=true;
> Form1.pFIBDataset2.Active:=true;
> Form1.pFIBDataSet3.Active:=true;
> end;
Так нельзя, все таки нужно синхронизировать. А OnGetText лечше все таки отключить. Это так:
Field1.OnGetText:=nil;
Включить:
Field1.OnGetText:=Field1OnGetText;
← →
Игорь Шевченко (2002-06-24 15:34) [23]Я бы посоветовал вам TFM все-таки почитать, оно полезно. Потому как одним отключением обработчика вы ситуацию не спасете. А проблем таким образом себе создадите.
← →
Tutov Roman (2002-06-24 15:39) [24]Да я -бы и рад почитать . Только где ? В примере что с дельфями идет я разобраться не смог ..(
← →
Игорь Шевченко (2002-06-24 15:42) [25]http://ibase.ru, к примеру. Раздел "Для разработчика"
← →
Lord Warlock (2002-06-24 15:44) [26]В общем, у меня получилось без Synchronize(В примере - компоненты ADO, IB у меня нет :) можешь попробовать.
uses ole2;
procedure TMyThreade.Execute;
begin
try
CoInitialize(Form1.ADOConnection1.VCLComObject);
Form1.ADOConnection1.Open;
Form1.ADOTable1.Open;
except
Terminate;
end;
end;
Для IB может не сработать...
← →
Tutov Roman (2002-06-24 15:50) [27]А что это ?
CoInitialize(Form1.ADOConnection1.VCLComObject);
← →
Lord Warlock (2002-06-24 15:52) [28]
> Tutov Roman (24.06.02 15:50)
а кто его знает :)
собственно это действие, предпринятое на соответствующую ошибку.
Попробуй переписать для IB/
Form1.ADOConnection1 это твоя Form1.pFIBDatabase1
← →
Tutov Roman (2002-06-24 15:59) [29]Lord Warlock © (24.06.02 15:52)
а кто его знает :)
Сильно !
← →
MBo (2002-06-24 16:07) [30]Ссылки на английском нужны?
← →
Tutov Roman (2002-06-24 16:09) [31]Нет . Ибо по не нашенски я не сильно...Но по русски только с радостью
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2002.09.05;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.008 c