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

Вниз

Вынесение запроса к базе в поток   Найти похожие ветки 

 
BorisUK   (2002-12-06 07:55) [0]

У меня трехзвенка, хочу вынести запрос с клиента к базе в поток...
Что делаю не так?

Почитал архив - там на все вопросы такого типа "Что сделать чтоб запрос можно было прервать?", "Чтоб прога не подвисала на время выполнения запроса?"
Все советовали поток... ОК
Создал.

В общем поток запускается (о чем сигнализирует метод монитор, показывая какой запрос пошел исполнятся),
какоето время обрабатывыет, а потом выдается ошибка
"Error reading from Socket" такая же ошибка сразу при попытке прервать поток...
При запуске из делфи дебагер перед этой ошибкой успевает еще сказать:
raised exception class EVariantError with message "Variant is not an array"

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

Помогите кто был успешнее в этом деле...
За рабочий пример буду блаодарен больше жизни :)

unit SQLExecThread;

interface

uses
Classes, dm_u, sysutils, wait_u;

type
TSQLExecThread = class(TThread)
private
StrMes : String;
{ Private declarations }
protected
procedure Execute; override;
procedure Monitor;

public
procedure SetSQL(s : String);

end;

implementation
var
SQLText : String;


procedure TSQLExecThread.SetSQL(s : String);
begin
SQLText:= s;
end;

procedure TSQLExecThread.Monitor;
begin
Wait_f.Label1.Caption:= StrMes;
end;

procedure TSQLExecThread.Execute;
var
i : integer;
begin
try
StrMes:=SQLText;
Synchronize(Monitor);
dm.ClientDataSet1.Active:=false;
dm.ClientDataSet1.CommandText:=SQLText;
dm.ClientDataSet1.Active:=true;
except
on E: Exception do
begin
StrMes:="шибка из потока "+e.Message;
Synchronize(Monitor);
end;
end;

if Terminated then
begin
exit;
end
end;

end.


Из главного окна проги делаю обработчик на кнопку

procedure TMain_f.bb_FindPPClick(Sender: TObject);
var
s : String;
begin
s:="Select * from Table1";
try
SQLExecThrd:=TSQLExecThread.Create(true);
SQLExecThrd.SetSQL(s);
SQLExecThrd.Resume;
SQLExecThrd.Priority:=tpLowest;
except
on E:Exception do
Showmessage("Ошибка в главном модуле "+e.message);
end;
//Вначале сделал вот так, но так виснет сразу
{ finally
SQLExecThrd.Terminate;
SQLExecThrd.Free;
end;}
end;


// Прерывание потока
procedure TMain_f.bb_BreakClick(Sender: TObject);
begin
if SQLExecThrd.Suspended then
SQLExecThrd.Resume;
SQLExecThrd.Terminate;
end;


 
ЮЮ   (2002-12-06 08:16) [1]

а dm.ClientDataSet1 синхронизировать не надо?

И это называется трехзвенка, когда клиент изменяет текст запроса?
Суть ClientDataSet-а, по-моему, в том, чтобы брать данные у Провайдера, а тот в свою очередь работал с сервером БД


 
BorisUK   (2002-12-06 08:19) [2]

Я примерно так и понял, что ктото чтото теперь не успевает передать,
но как синхронизировать... подскажите плз а то у меня затмение :(


 
sniknik   (2002-12-06 08:25) [3]

ну есть пару вещей которые я бы изменил (применительно к потоку), по базе думаю это только наметки (проба), а так вроде все нормально.
try
try
SQLExecThrd:=TSQLExecThread.Create(true);
SQLExecThrd.SetSQL(s);
SQLExecThrd.Priority:=tpNormal; //а то тормозить будет
SQLExecThrd.FreeOnTerminate:= false; //чтобы работало завершение как у тебя
SQLExecThrd.Resume;
except
on E:Exception do
Showmessage("Ошибка в главном модуле "+e.message);
end;
// вот это теперь должно работать от FreeOnTerminate
finally
SQLExecThrd.Terminate;
SQLExecThrd.WaitFor; //ждать окончания запроса пока не отработал убивать нельзя
SQLExecThrd.Free;
end;

ну и бработчик в "скобочки" хотя и без этого работает проверял но в хелпе пишут так надо
procedure TSQLExecThread.Execute;
var
i : integer;
begin
CoInitialize(nil);
... код //но его бы посложней просто один запрос можно и асинхронно выполнить чтобы не тормозило
CoUnInitialize();
end;


 
BorisUK   (2002-12-06 09:12) [4]

CoInitialize(nil);
CoUnInitialize();
На них матерится.. говорит
-- Undeclared identifier: "CoInitialize"
А так в общем заработало, но как попало :(
Помогли оба совета...
<<ЮЮ ©
Синхронизировал вроде - хотя может не то сделал...
Вынес получение данных в процедуру потока

procedure TSQLExecThread.ResiveData;
begin
dm.CDS_V_DocTree.Active:=true;
wait_f.close;
end;

В execute вызываю её

procedure TSQLExecThread.Execute;
var
i : integer;
begin
try
// CoInitialize(nil);
dm.CDS_V_DocTree.Active:=false;
dm.CDS_V_DocTree.CommandText:=SQLText;
Synchronize(ResiveData);

except
on E: Exception do
begin
StrMes:=e.Message;
Synchronize(Monitor);
end;
end;

if Terminated then
begin
wait_f.close;
exit;
end;
// CoUnInitialize();
end;

Но теперь все работает как до потока было...
Пока данные не получатся вся прога подвисает...
У меня перед запуском потока вызывается формочка с програссбаром, на ней таймер который задает движение на прогрессбаре (чтоб юзеру не скучно было) Так вот он теперь тоже не идет ... Тоесть пока
dm.CDS_V_DocTree.Active:=true не выполнится
зависает все :(

В общем для чего старался - чтоб запрос прерывать можно было и визуализировать процесс ожидания - Того и не вышло пока...

Может что ещё подскажете?


 
sniknik   (2002-12-06 11:18) [5]

логику поменяй. не жди завершения, к примеру можно открывать поток в начале проги и закрывать в конце управляя им по "ходу пьесы", при открытии пускать процесс, а при завершении запроса генерить событие.

посмотри еще хелп по ADODataSet.ExecuteOptions может это тебе больше подойдет.



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

Форум: "Базы";
Текущий архив: 2002.12.26;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.007 c
14-86084
Феликс
2002-12-07 16:40
2002.12.26
Вопрос по прокси


7-86186
Serg T
2002-09-16 13:17
2002.12.26
Кулер


3-85855
jen_bond
2002-12-07 09:54
2002.12.26
Округление


14-86112
Дядя Вел
2002-12-03 18:40
2002.12.26
Wake UP on LAN


14-86093
RV
2002-12-05 10:14
2002.12.26
Задачка :)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский