Данная статья посвящена асинхронному выполнению в FireDAC. Она основана на официальной документации
Программист может выбирать между 4 режимами, используя свойство ResourceOptions.CmdExecMode
Далее, в документации приводится такая таблица
Приложение проверяет статус TFDCommand.State илиTFDAdaptedDataSet.Command.State
Например, можно сделать таким образом
1 2 3 4 5 |
FDQuery1.ResourceOptions.CmdExecMode := amAsync; FDQuery1.Open; while FDQuery1.Command.State = csExecuting do begin // do something while query is executing end; |
Если операция долгая, можно использовать специальный диалог TFDGUIxAsyncExecuteDialog. Для этого достаточно добавить его на форму и выбрать ResourceOptions.CmdExecMode:=amCancelDialog
Асинхронное открытие и получение (Asynchronous Open and Fetching)
Когда приложение должно открыть запрос асинхронно, и запрос связан с GUI, используя TDataSource, то TDataSource должен быть отсоединен от запроса до открытия и соединен обратно после открытия query, например
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
procedure TForm1.FDQuery1BeforeOpen(DataSet: TDataSet); begin DataSource1.DataSet := nil; end; procedure TForm1.FDQuery1AfterOpen(DataSet: TDataSet); begin DataSource1.DataSet := FDQuery1; FDQuery1.ResourceOptions.CmdExecMode := amBlocking; end; FDQuery1.BeforeOpen := FDQuery1BeforeOpen; FDQuery1.AfterOpen := FDQuery1AfterOpen; FDQuery1.ResourceOptions.CmdExecMode := amAsync; FDQuery1.Open; |
Этого не требуется когда используется amCancelDialog. Также, получение с GUI не может быть подготовлено в amAsync режиме. Чтобы открыть запрос и получить большое множество асинхронно, установите FetchOptions.Mode в режим fmAll. Тогда обе операции будут происходить в бэкграунд режиме. Этот процесс возможно только при двунаправленных курсорах.
Выход из длинных операций
Программист может вручную ограничивать время выполнения операций.
1 2 3 4 5 6 7 8 9 |
try // set timeout to 5 seconds FDQuery1.ResourceOptions.CmdExecTimeout := 5000; FDQuery1.ExecSQL; except on E: EFDDBEngineException do if E.Kind = ekCmdAborted then ; // command is aborted end; |
Альтернативно можно использовать метод AbortJob из другого потока либо этот же метод для FDConnection
Множественные асинхронные запросы. (Multiple Asynchronous Queries)
Не поддерживаются FireDAC. Но можно поступить следующим образом
-Группировать несколько запросов в хранимую процедуру и вызывать процедуру асинхронно
-Использовать отдельное соединение для каждого асинхронного запроса, запускаемого параллельно
-Запускать следующий асинхронный запрос только после того как предыдущий будет закончен. Для этого можно использовать AfterOpen и AfterExecute
-В конце концов, приложение может использовать потоки и исполнять запросы в отдельных потоках