Советы по Delphi. Версия 1.4.3 от 1.1.2001 - страница 29

стр.

Эти требования обязательны при разработке многопользовательских приложений Delphi с использованием файлов Dbase или Paradox.

– Ted Bulmanski

Выполнение запросов к базе данных в фоне

Delphi 2

Тема: Выполнение запросов к базе данных в фоновом потоке

Данный документ объясняет как выполнить запрос в фоновом режиме, используя класс TThread. Для получения общей информации о классе TThread, пожалуйста обратитесь к документации Borland и электронной справке. Для понимания данного документа вам необходимо иметь представление о том, как работать с компонентами для работы с базами данных, поставляемых в комплекте с Delphi 2.0.

Для осуществления потокового запроса необходимо выполнение двух требований. Во-первых, потоковый запрос должен находиться в своей собственной сессии с использованием отдельного компонента TSession. Следовательно, на вашей форме должен находиться компонент TSession, имя которого должно быть назначено свойству SessonName компонента TQuery, используемого для выполнения потокового запроса. Для каждого используемого в потоке компонента TQuery вы должны использовать отдельный компонент TSession. При использовании компонента TDataBase, для отдельного потокового запроса должен также использоваться отдельный TDataBase. Второе требование заключается в том, что компонент TQuery, используемый в потоке, не должен подключаться в контексте это потока к TDataSource. Это должно быть сделано в контексте первичного потока.

Приведенный ниже пример кода иллюстрирует описываемый процесс. Данный модуль демонстрирует форму, которая содержит по два экземпляра следующих компонентов: TSession, TDatabase, TQuery, TDataSource и TDBGrid. Данные компоненты имеют следующие значения свойств:

>Session1

> Active True;

> SessionName "Ses1"


>DataBase1

> AliasName "IBLOCAL"

> DatabaseName "DB1"

> SessionName "Ses1"


>Query1

> DataBaseName "DB1"

> SessionName "Ses1"

> SQL.Strings "Select * from employee"


>DataSource1

> DataSet ""


>DBGrid1

> DataSource DataSource1


>Session2

> Active True;

> SessionName "Ses2"


>DataBase2

> AliasName "IBLOCAL"

> DatabaseName "DB2"

> SessionName "Ses2"


>Query2

> DataBaseName "DB2"

> SessionName "Ses2"

> SQL.Strings "Select * from customer"


>DataSource2

> DataSet ""


>DBGrid1

> DataSource DataSource2

Обратите внимание на то, что свойство DataSet обоих компонентов TDataSource первоначально никуда не ссылается. Оно устанавливается во время выполнения приложения, и это проиллюстрировано в коде.

>unit Unit1;


>interface


>uses Windows, Messages, SysUtils, Classes, Graphics, Controls,Forms, Dialogs,StdCtrls, Grids, DBGrids, DB, DBTables;


>type

> TForm1 = class(TForm)

>  Session1: TSession;

>  Session2: TSession;

>  Database1: TDatabase;

>  Database2: TDatabase;

>  Query1: TQuery;

>  Query2: TQuery;

>  DataSource1: TDataSource;

>  DataSource2: TDataSource;

>  DBGrid1: TDBGrid;

>  DBGrid2: TDBGrid;

>  GoBtn1: TButton;

procedure GoBtn1Click(Sender: TObject);

end;


> TQueryThread = class(TThread)

private

>FSession: TSession;

>  FDatabase: TDataBase;

>  FQuery: TQuery;

>  FDatasource: TDatasource;

>  FQueryException: Exception;

procedure ConnectDataSource;

procedure ShowQryError;

protected

>  procedure Execute; override;

public

>  constructor Create(Session: TSession; DataBase: TDatabase; Query: TQuery; DataSource: TDataSource); virtual;

end;


>var Form1: TForm1;


>implementation


>constructor TQueryThread.Create(Session: TSession; DataBase: TDatabase; Query: TQuery; Datasource: TDataSource);

>begin

> inherited Create(True); // Создаем поток c состоянием suspendend

> FSession := Session;     // подключаем все privat-поля

> FDatabase := DataBase;

> FQuery := Query;

> FDataSource := Datasource;

> FreeOnTerminate := True; // Устанавливаем флаг освобождения потока после его завершения

> Resume;                  // Продолжение выполнения потока

>end;


>procedure TQueryThread.Execute;

>begin

> try

>{ Выполняем запрос и подключаем источник данных к компоненту TQuery, вызывая ConnectDataSource из основного потока(для этой цели используем Synchronize)}

>  FQuery.Open;

>  Synchronize(ConnectDataSource);

except

>{ Ловим исключение (если оно происходит) и его дескриптор в контексте основного потока (для этой цели используемSynchronize). }