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

Советы » Компоненты и Базы данных » Выполнение запросов к базе данных в фоне

Данный документ объясняет как выполнить запрос в фоновом режиме, используя класс 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). } FQueryException := ExceptObject as

Exception; Synchronize(ShowQryError); end

; end

; procedure

TQueryThread.ConnectDataSource; begin

FDataSource.DataSet := FQuery; // Подключаем DataSource к TQuery end

; procedure

TQueryThread.ShowQryError; begin

Application.ShowException(FQueryException); // Обрабатываем исключение end

; procedure

RunBackgroundQuery(Session: TSession; DataBase: TDataBase; Query: TQuery; DataSource: TDataSource); begin

{ Создаем экземпляр TThread с различными параметрами. } TQueryThread.Create(Session, Database, Query, DataSource); end

; {$R *.DFM} procedure

TForm1.GoBtn1Click(Sender: TObject); begin

{ Запускаем два отдельных запроса, каждый в своем потоке } RunBackgroundQuery(Session1, DataBase1, Query1, Datasource1); RunBackgroundQuery(Session2, DataBase2, Query2, Datasource2); end

; end

.

Метод TForm1.GoBtn1Click является обработчиком события нажатия кнопки. Данный обработчик события дважды вызывает процедуру RunBackgroundQuery, это случается при каждой передаче новых параметров компонентам для работы с базой данных. RunBackgroundQuery создает отдельный экземпляр класса TQueryThread, передает различные компоненты для работы с базой данных в его конструктор, который, в свою очередь, назначает их закрытым полям TQueryThread.

TQueryThread содержит две определенные пользователем процедуры: ConnectDataSource и ShowQryError. ConnectDataSource связывает FDataSource.DataSet с FQuery. Тем не менее, это делается в первичном потоке с помощью метода TThread.Synchronize. ShowQryError обрабатывает исключение в контексте первиного потока, также используя метод Synchronize. Конструктор Create и метод Execute снабжены подробными комментариями.

Другое по теме:

Категории

Статьи

Советы

Copyright © 2022 - All Rights Reserved - www.delphirus.com