AnyDAC offers multiple features for asynchronous operation execution. In addition to being ready for use in multi-threaded applications, AnyDAC makes it easy for the developer to not have to worry about multi-threading in the first place by allowing you to control the timing aspects of the data access operation execution. This includes Execute, Open and Fetch operations.
A programmer may choose between four operation modes using the ResourceOptions.CmdExecMode property:
|
Mode |
Description |
|
amBlocking |
The calling thread and GUI are blocked until an action will be finished. |
|
amNonBlocking |
The calling thread is blocked until an action will be finished. The GUI is not blocked. |
|
amCancelDialog |
The calling thread and GUI are blocked until an action will be finished. AnyDAC shows dialog, allowing to cancel an action. |
|
amAsync |
The calling thread and GUI are not blocked. The called method will return immediately. |
An application may check TADCommand.State or TADAdaptedDataSet.Command.State for an operation status:
|
Status |
Description |
|
csInactive |
A command is not prepared. |
|
csPrepared |
A command is prepared. A result set is not accessible. |
|
csExecuting |
A command execution is in progress. |
|
csOpen |
A command execution is finished. A result set is accessible and not yet fetched in full. |
|
csFetching |
A result set fetching is in progress. |
|
csAborting |
A command execution abortion is in progress. |
For example:
ADQuery1.ResourceOptions.CmdExecMode := amAsync; ADQuery1.Open; while ADQuery1.Command.State = csExecuting do begin // do something while query is executing end;
With help of TADGUIxAsyncExecuteDialog component, in the amCancelDialog mode a user may be notified about long running operations and have an ability to cancel operation:
To use the dialog component, drop it on a form. No additional setup is required. Read more about modes and operation notification events at ResourceOptions.CmdExecMode property description.
When an application needs to open a query pure asynchronously (amAsync) and the query is bind to the GUI using TDataSource, then before opening the query TDataSource must be disconnected from the query and after opening connected back. For example:
procedure TForm1.BeforeOpen(DataSet: TDataSet); begin DataSource1.DataSet := nil; end; procedure TForm1.AfterOpen(DataSet: TDataSet); begin DataSource1.DataSet := ADQuery1; ADQuery1.ResourceOptions.CmdExecMode := amBlocking; end; ADQuery1.BeforeOpen := ADQuery1BeforeOpen; ADQuery1.AfterOpen := ADQuery1AfterOpen; ADQuery1.ResourceOptions.CmdExecMode := amAsync; ADQuery1.Open;
That is not required when amCancelDialog is used. Also fetching with GUI cannot be performed in amAsync mode. To perform opening a query and fetching large result set asynchronously set FetchOptions.Mode = fmAll. Then both operations will be performed as a single background task. Note, that it is only valid when you need a bi-directional dataset.
To asynchronously execute Firebird query use separated transaction for this query.
A programmer can specify the timeout for the data access operation using the ResourceOptions.CmdExecTimeout property. When an operation execution requires more than the specified time, then the execution will be canceled and exception will be raised. To catch a command timeout use the code:
try // set timeout to 5 seconds ADQuery1.ResourceOptions.CmdExecTimeout := 5000; ADQuery1.ExecSQL; except on E: EADDBEngineException do if E.Kind = ekCmdAborted then ; // command is aborted end;
Alternatively application may cancel operation execution by calling dataset or command AbortJob method from other thread. Or call connection AbortJob method to cancel all operations on this connection.
Note, that not all AnyDAC drivers and DBMS are supporting execution cancellation. Also the cancellation may be performed not immediately, when A DBMS is performing some critical operations. The following table lists supported combinations:
|
DBMS |
Notes |
|
Advantage |
|
|
Firebird |
v 2.5 or higher |
|
IBM DB2 |
|
|
Interbase |
v 7.0 or higher |
|
MySQL |
v 5.0 or higher |
|
Oracle |
|
|
PostgreSQL |
|
|
SQL Anywhere |
|
|
SQL Server |
|
|
SQLite |
|
Execution of the multiple asynchronous queries in parallel is not supported by AnyDAC, due to the general multi-threading principle. To workaround that consider the options:
|
What do you think about this topic? Send feedback!
|