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

Вниз

Передача данных запроса к БД из потока   Найти похожие ветки 

 
galexis ©   (2004-09-06 13:46) [0]

Пытаюсь работать с потоками (TThread). В потоке выполняется запрос к БД FireBird. А что делать с набором данных после этого не знаю. Как передать их в основной поток? Сейчас провожу эксперименты с SendMessage, но думаю что это не выход, да и с ним у меня пока еще ничего не вышло. Приложение у меня MDI, а поток создается из дочернего окна. Как обратиться к элементу редактирования TEdit, который расположен в таком окне?
Помогите разобраться пожалуйста.


 
Карелин Артем ©   (2004-09-06 13:51) [1]

Разберись с основами синхронизации потоков. Конкретно Synchronize


 
galexis ©   (2004-09-06 14:05) [2]


> Карелин Артем ©  

Где бы прочитать в интернте про это. У меня есть распечатка главы "Создание многопоточных приложений" из какой то книги. В данный момент как раз открыта на Synchronize. С примером, где сообщение передается непосредственно в основной поток, а я к нему и обратится не могу, форма то дочерняя


 
Digitman ©   (2004-09-06 14:13) [3]


> сообщение передается непосредственно в основной поток, а
> я к нему и обратится не могу, форма то дочерняя


???


 
Карелин Артем ©   (2004-09-06 14:15) [4]

Не надо сообщения мучать. Пиши просто edit1212.text:=запрос.поле1.какстрока в методе, который будешь вызывать посредством Synchronize


 
galexis ©   (2004-09-06 14:28) [5]


> Digitman ©

Не могу обратиться к элементу TEditиз потока, ну например надо написать
FindForm.Edit1.Test:=...; Но Форма FindForm у меня MDIChild, т.е. к ней надо обращаться как
MainForm.MDIChildren[0]. А как обратиться к элементу Edit1 на ней?


 
galexis ©   (2004-09-06 14:29) [6]

>Карелин Артем © Вот к edit1212.text я и не могу обратиться.


 
galexis ©   (2004-09-06 14:43) [7]

Могу вот так сообщение переслать
SendMessage(MainForm.MDIChildren[0].ActiveControl.Handle,WM_SETTEXT,0,Integer(PChar(cnt)));
Но это не выход. А как можно передать набор данных и поместить его в DBGrid?


 
Reindeer Moss Eater ©   (2004-09-06 14:58) [8]

TDataSource + TDBGrid


 
galexis ©   (2004-09-06 15:16) [9]


> Reindeer Moss Eater ©

Это понятно, а если TDBGrid находится на форме FindForm, которая MDIChild?


 
Romkin ©   (2004-09-06 15:29) [10]

Элегантный выход - TClientDataset. Удивлены? Все просто, в Execute потока создавайте модуль данных с T...Query и TDatasetProvider (именно в execute ;) ). Делайте, что угодно. Потом просто передайте данные из провайдера в TClientDataSet на форме (эссно в Syncronize). И все. У вас есть набор данных, с которым вы можете делать все. Уже в основном потоке :))


 
Reindeer Moss Eater ©   (2004-09-06 15:31) [11]

Это понятно, а если TDBGrid находится на форме FindForm, которая MDIChild?

А какая разница где именно она "находится"?


 
galexis ©   (2004-09-06 15:41) [12]


> Reindeer Moss Eater ©

Разница в том, что нельзя обратиться к TDBGrid обычным образом, т.е. нельзя написать FindForm.DBGrid1.DataSource.
Форма создается в процессе работы приложения и не имеет имени, к ней можно обратиться как MainForm.MDIChildren[0] Как обратиться при этом к конкретному компоненту, а мне надо DBGrid я не знаю. Точнее знаю. Надо сделать его активным и обращаться к нему как MainForm.MDIChildren[0].ActiveControl. Но это не очень хорошо.


 
Reindeer Moss Eater ©   (2004-09-06 15:43) [13]

Дык у тебя вопрос про то как найти экземпляр формы.

При чем здесь вся предыдущая канитель со вторичными потоками?
К делу не относящаяся.


 
galexis ©   (2004-09-06 15:46) [14]


> Romkin ©  

Пока еще до меня не дошло в полной мере, то что вы предложили. Но, по моему, если я расположу TClientDataset на моей форме FindForm, я и к этому компоненту не смогу обратиться. вот если только его расположить на MainForm.


 
Reindeer Moss Eater ©   (2004-09-06 15:47) [15]

вот если только его расположить на MainForm.

Он там один, а MDI Child"ов - много.
Как делить будем?


 
galexis ©   (2004-09-06 15:48) [16]


> Reindeer Moss Eater ©

Ну задача у меня стоит как передать набор данных из вторичного потока в основной. А уж все остальное это попутно.


 
Reindeer Moss Eater ©   (2004-09-06 15:49) [17]

Никуда наборы данных не передаются.
Они остаются там где были созданы.
Вплоть до закрытия и деструктора.


 
Digitman ©   (2004-09-06 15:50) [18]


> galexis ©   (06.09.04 14:28) [5]


см. [13]

???


 
galexis ©   (2004-09-06 16:05) [19]


> Digitman ©

Да я и не спорю. Но и ясности у меня так и нет. Вот выполнился во вторичном потоке у меня запрос к БД. Теперь IBQuery содержит набор данных. На форме из которой был создан вторичный поток есть DBGrid. Как заполнить DBGrid данными из IBQuery вторичного потока?


 
Reindeer Moss Eater ©   (2004-09-06 16:06) [20]

Как заполнить DBGrid данными из IBQuery вторичного потока?

DBGrid.DataSource:=MySource;
MySource.DataSet:=MyDataSet;


 
Digitman ©   (2004-09-06 16:07) [21]


> На форме из которой был создан вторичный поток


почему бы форме, создавшей вторичный поток, не передать параметром в этот поток ссылку на себя ? и искать же ничего не нужно будет !


 
galexis ©   (2004-09-06 16:12) [22]


> Digitman ©

Если бы я знал как это сделать? Есть правда в Demos от Delphi примерчик. Там как раз и передаются многие параметры. Опять же все как то мудрено там


 
Reindeer Moss Eater ©   (2004-09-06 16:17) [23]

Передача параметров - мудрено?
Ну ну.

Стоит ли вообще браться за программирование?

...
with TMyThread.Create(MyDBGrid) do
resume;
...


 
galexis ©   (2004-09-06 16:23) [24]


> Reindeer Moss Eater ©

Мудрено в примерчике. Там используется конструктор. Примерчик называется ThreadedQuery.
За программирование браться не стоит, если это не основная работа и не хобби. У меня как раз не то, не то. Я вообще хочу начальником быть :)


 
Reindeer Moss Eater ©   (2004-09-06 16:26) [25]

Мудрено в примерчике. Там используется конструктор.

Конструкторы везде используются где есть классы.
В том числе и в твоих программах написанных ранее.
Не только в том примерчике.


 
Digitman ©   (2004-09-06 16:30) [26]


> Я вообще хочу начальником быть


не то, брат, не то ... настоящие начальники должны как минимум уметь писать "ни то ни другое", ну и опционально - уметь передавать в конструирующий метод произвольного класса (причем по барабану какого - TThread или TSomeClass) некие параметры


 
Анонимщик ©   (2004-09-06 16:36) [27]

Вот почти один-в-один то, что нужно:

http://www.instantchess.com/?EC=3&EXP=1&FindPl=%C2%EE%E2%EA&SUH=1&Date1=38229&RT2=1#4


 
Анонимщик ©   (2004-09-06 16:46) [28]

Пардон,

http://www.delphiworld.narod.ru/base/background_db_queries.html


 
galexis ©   (2004-09-06 16:47) [29]


> Digitman ©  

По поводу передавать в конструирующий метод это все поправимо, а вот начальником стать труднее. Я вот работаю в отделе программного обеспечения в структуре власти. По образованию физик. А два моих начальника (точнее начальник и его зам.) один, врач второй сантехник. А вы мне про ни то ни другое. Мне бы примерчик простенький, или ссылку на статейку по теме.


 
galexis ©   (2004-09-06 16:51) [30]


> Анонимщик ©   (06.09.04 16:46) [28]

О! Вот за это спасибо


 
galexis ©   (2004-09-06 16:54) [31]


> Анонимщик ©

Упс! А IBQuery не может работать с TSession :(


 
Анонимщик ©   (2004-09-06 16:55) [32]

Я же сказал, что почти, а не именно то. Тем более, что тебе для IB сессии не нужны вовсе. Делай отдельный подключения в каждом потоке.


 
Digitman ©   (2004-09-06 16:56) [33]


> galexis ©   (06.09.04 16:47) [29]


я-то ждал иного вопроса - "подскажите ссылку на инф-цию о принципах передачи параметров в методы Делфи-объектов" ... а в ответ - про сантехников и физиков .. печально это


>не основная работа и не хобби
> ..
> в отделе программного обеспечения в структуре власти


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


 
Анонимщик ©   (2004-09-06 16:58) [34]

Как ты все же утомил всех:

unit IBBackGroundQuery;

interface

uses
 Classes, IBDataBase, IBQuery, SysUtils, Messages, Forms, DB, Windows;

type
 TIBBackGroundQuery = class(TThread)
 private
   { Private declarations }
   FDBName      : String;
   FSQLString   : String;
   FDBParams    : TStringList;

   FIBDB        : TIBDataBase;
   FIBT         : TIBTransaction;
   FIBQSequences: TIBQuery;
   FDS          : TDataSource;
   FQueryException: Exception;

   // обработка исключения, связанного с ошибкой выполнения запроса
   procedure ShowQryError;
   procedure ConnectDataSource;
 protected
   procedure Execute; override;
 public
   constructor Create(ADBName: String; ADBParams: TStrings;
                      const ASQLString: String; const ADS: TDataSource); virtual;
   destructor Destroy; override;
 end;

implementation

{ Important: Methods and properties of objects in VCL or CLX can only be used
 in a method called using Synchronize, for example,

     Synchronize(UpdateCaption);

 and UpdateCaption could look like,

   procedure TIBBackGroundQuery.UpdateCaption;
   begin
     Form1.Caption := "Updated in a thread";
   end; }

{ TIBBackGroundQuery }

constructor TIBBackGroundQuery.Create(ADBName: String; ADBParams: TStrings;
                                     const ASQLString: String; const ADS: TDataSource);
begin
 inherited Create(false);

 FDBName    := ADBName;
 FDBParams  := TStringList.Create;
 FDBParams.Assign(ADBParams);
 FSQLString := ASQLString;

 FDS := ADS;
 FreeOnTerminate := false;
end;

destructor TIBBackGroundQuery.Destroy;
begin
 inherited;
 FIBDB.Free;
 FIBT.Free;
 FIBQSequences.Free;
end;

procedure TIBBackGroundQuery.ShowQryError;
begin
 Application.ShowException(FQueryException);
end;

procedure TIBBackGroundQuery.ConnectDataSource;
begin
 FDS.DataSet := FIBQSequences;
 FDS.DataSet.Active := true;
end;

procedure TIBBackGroundQuery.Execute;
begin
 { Place thread code here }
 try
 FIBDB:= TIBDataBase.Create(nil);
 FIBDB.LoginPrompt := false;
 FIBT := TIBTransaction.Create(nil);
 FIBDB.DatabaseName := FDBName;
 FIBDB.Params.Assign(FDBParams);
 FDBParams.Free;
 FIBT.Params.Clear;
 FIBT.Params.Add("read_committed");
 FIBT.Params.Add("rec_version");
 FIBT.Params.Add("nowait");
 FIBDB.DefaultTransaction := FIBT;
 FIBT.DefaultDatabase := FIBDB;
 FIBQSequences:= TIBQuery.Create(nil);
 FIBQSequences.Database := FIBDB;
 FIBQSequences.Transaction := FIBT;
 FIBQSequences.SQL.Clear;
 FIBQSequences.SQL.Add(FSQLString);

 FIBQSequences.Open;
 Synchronize(ConnectDataSource);
 except
   FQueryException := ExceptObject as Exception;
   Synchronize(ShowQryError);
 end;
end;

end.


 
galexis ©   (2004-09-06 17:03) [35]


> Digitman ©

Так и есть, кушать хочется!


 
galexis ©   (2004-09-06 17:12) [36]


> Анонимщик ©   (06.09.04 16:58) [34]

Только не убивайте..
Можно теперь кусочек кода создания этого потока?


 
Анонимщик ©   (2004-09-06 17:19) [37]

Интересно, что ты с ним делать будешь?

var
 IBBackQ: TIBBackGroundQuery;
begin
 IBBackQ := TIBBackGroundQuery.Create("127.0.0.1:c:\1.gdb", nil, "select g from alexis", MyDS);


 
Digitman ©   (2004-09-06 17:20) [38]

это называется - "дай г., дай ложку"


 
galexis ©   (2004-09-06 17:29) [39]


> Анонимщик ©

А как передавать параметры БД, которые nil?


 
Reindeer Moss Eater ©   (2004-09-06 17:33) [40]

Усыпите его кто-нибудь уже.



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

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

Наверх




Память: 0.57 MB
Время: 0.023 c
1-1095679598
Krot
2004-09-20 15:26
2004.10.03
Вопрос по реестру в WinXP(проблемы с удалением параметра)


14-1095248996
NewDelpher
2004-09-15 15:49
2004.10.03
Перестала запускаться DELPHI


3-1094639300
DBL
2004-09-08 14:28
2004.10.03
Импорт (добавление)


1-1095409645
TUser
2004-09-17 12:27
2004.10.03
Delphi < --- > CB


8-1087894955
Borealis
2004-06-22 13:02
2004.10.03
Изображения ключевых кадров из авишки (RIFF_AVI)