![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ADO внутри потока [D7]
patrick1968 © (2008-02-13 18:38:00)При обработке потока столкнулся с такой проблемой, при открытии запроса оракла через компоненты ADO поток подвисает, вычитал на форуме, что надо делать примерно так
procedure TMainThread.Execute;
begin
CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
while not Terminated do
begin
Synchronize(DoWork);
Sleep(1000);
end;
CoUnInitialize;
end;
procedure TMainThread.DoWork;
begin
... вот как раз зависает тут
Unload.OraQuery.Parameters.ParamByName('MX').Value := MX;
Unload.OraQuery.Open;
...
end;
может подскажет кто-нибудь решение проблемы
Германн (2008-02-14 13:21:00) [1]
> sniknik © (14.02.08 08:20) [7]
>
> > Статью Коли Рариха вроде уже давно убрали с нашего сайта.
> Или я ошибаюсь?
> вот уж не знал что такая есть... но действительно есть
> http://www.delphimaster.ru/articles/http/index.html(ВНИМАНИЕ,
> в указанной статье работа с потоком идет принципиально
> неверно. НЕ ИСПОЛЬЗОВАТЬ!!!)
> даже сюда при общем нетерпении последователь Архангельского
> пробрался... :)
Ууу, блин. А про эту статью я и не знал. Я то говорил про статью посвященную именно работе с потоками, которая довела цифрочеловека до ручки. Её действительно давно убрали.
Сергей М. (2008-02-14 12:14:00) [2]
> patrick1968 © (14.02.08 12:03) [16]
Да и, собственно, совет вынести работу с ADO в доп.поток, который тебе был дан по поводу предыдущего твоего вопроса по сервису, тоже можно считать вредным, ибо ты не осознаешь, для чего оно тебе надо.
sniknik (2008-02-14 12:06:00) [3]аналогия...
не заводится машина, ктото советует "а давайте толканем", толканули, завели поехали... в автомастерскую. :)
а ты на это смотришь и решаешь "о, а нафига на бензин тратиться? а давай ка я буду ездить толканием"...
и? предыдущий совет про "толканем" будет вредным? или неверно исключительно твое понимание для чего его использовать?
Сергей М. (2008-02-14 12:05:00) [4]Прямо так и понимай - ты содрал код из примера, ни секунды не задумываясь над происходящем в этом коде.
patrick1968 (2008-02-14 12:03:00) [5]Как вас понимать?
Сергей М. (2008-02-14 11:58:00) [6]Если Вам необходимо из потока обновлять переменные и объекты, которые используются вне этого потока, всегда пользуйтесь методом Synchronize
Вот это оченьвредный совет.
sniknik (2008-02-14 11:55:00) [7]> Так вот - это вредные советы или нет?
это нормальные. правильные, и понятные... в них описана цель. и показано как/чем она достигается.
Сергей М. (2008-02-14 11:52:00) [8]
> это вредные советы или нет?
При бездумном чтении статьи и бездумном же передирании примера в свой код - безусловно, вредные.
Именно это ты и продемонстрировал)
patrick1968 (2008-02-14 11:44:00) [9]Вот Palladin тоже так считает, но согластно ссылке, которую он любезно предоставил http://www.delphimaster.ru/articles/panov/index.html
есть такой текст
Execute.
В Execute должен выполняться весь код, который должен выполняться «параллельно» основному потоку. Как правило, если поток предназначен для выполнения многократно повторяющегося кода (цикла), то в Execute используется конструкция следующего вида:
while not Terminated do
begin
// В этом месте выполняется весь необходимый код.
…
// Если здесь необходимо обновлять некоторые данные в основном потоке,
// то здесь используйте метод Synchronize.
Synchronize(MyUpdateProcedure);
// Процедуру MyUpdateProcedure определяем в описании нашего класса.
end;
Synchronize
Так как процедура, вызываемая в методе Synchronize выполняется в основном потоке, то на время выполнения Synchronize главная форма будет блокирована для ввода, обновления информации, как это происходит при длительных операциях в основном потоке.
Поэтому этот метод надо вызывать по возможности реже.
Простейший пример таймера:
procedure MyThread.MyUpdateProcedure;
begin
FormMain.LabelCounter.Caption := IntToStr(FCounter);
end;
procedure MyThread.Execute;
begin
while not Terminated do
begin
Inc(FCounter);
Synchronize(MyUpdateProcedure);
Sleep(1000);
end;
end;
Если Вам необходимо из потока обновлять переменные и объекты, которые используются вне этого потока, всегда пользуйтесь методом Synchronize. Результат обновления прямо из Execute или других процедур, определенных в потоке, может быть непредсказуемым, вплоть до возникновения исключительной ситуации(Exception)
Так вот - это вредные советы или нет?
Сергей М. (2008-02-14 11:17:00) [10]
> результат тот же
А куда он денется, этот результат, если ты по-прежнему пытаешься воспользоваться вредными советами Архангельского, Кариха и иже с ними ?)
patrick1968 (2008-02-14 11:14:00) [11]Имеется ввиду свойство ConnectOptions у TADOConnection тоже пробовал менять на coAsyncConnect - результат тот же.
sniknik (2008-02-14 10:01:00) [12]> возможно, в нем тоже есть асинхронный режим.
почему только возможно? точно есть. но вопрос конкретно о "ADO внутри потока". а не о том какой лучший способ для ... "делается вот это" ....
ANB (2008-02-14 09:04:00) [13]
> при открытии запроса оракла через компоненты ADO
Используй нативные способы доступа к ораклу - там есть асинхронное выполнение запроса без доп.потоков.
ИМХО : использование потоков для асинхронного доступа к серверным СУБД - извращение, только маскирующее проблему и создающее доп. сложности. Кстати, можно и АДО покопать, возможно, в нем тоже есть асинхронный режим.
sniknik (2008-02-14 08:20:00) [14]> Статью Коли Рариха вроде уже давно убрали с нашего сайта. Или я ошибаюсь?
вот уж не знал что такая есть... но действительно есть
http://www.delphimaster.ru/articles/http/index.html(ВНИМАНИЕ, в указанной статье работа с потоком идет принципиально неверно. НЕ ИСПОЛЬЗОВАТЬ!!!)
даже сюда при общем нетерпении последователь Архангельского пробрался... :)
Германн (2008-02-14 01:53:00) [15]
> вычитал на форуме, что надо делать примерно так
>
Это на каком форуме? На нашем форуме это как красная тряпка для быка, который помимо прочего выделяет из всех людей Архангельского и его читателей/последователей.
P.S.
Статью Коли Рариха вроде уже давно убрали с нашего сайта. Или я ошибаюсь?
sniknik (2008-02-13 23:22:00) [16]> Имеешь ввиду что Execute у потока также не надо пользовать как и у службы
с чего это Execute не использовать? использовать можно все что нужно в нужном месте... в том числе и Execute у службы.
а указывали тебе, выделили Synchronize с DoWork, не делать так как у тебя с ними. только не интерпретируй так что ее вообще нельзя использовать... когда нужно она весьма полезна. но не в таком контексте как у тебя. а вот для того чтобы различать когда нужно, а когда вредно тебе и предлагали подумать(/найти/почитать) о том зачем нужна функция и что с ее вызовом происходит. должен же понимать что пишешь, а не просто набор заклинаний отовсюду в свою прогу копировать...
patrick1968 (2008-02-13 19:54:00) [17]Имеешь ввиду что Execute у потока также не надо пользовать как и у службы, только в статьях на сей счет противоречивая инфа.
Palladin (2008-02-13 19:48:00) [18]а вот не надо так делать... я тебе намекал намекал ознакомиться поподробней, а не тупо копировать... ты так ничего и не понял... доктор сказал в морг значит в морг...
patrick1968 (2008-02-13 19:43:00) [19]Дык и так делал - ситуация таже самая
Ega23 (2008-02-13 19:36:00) [20]
> может подскажет кто-нибудь решение проблемы
>
конечно. Не надо читать Архангельского.
while not Terminated do
begin
Synchronize(DoWork);
Sleep(1000);
end;
Как ты думаешь, что тут происходит?