A thread-based asynchronous database query component for modern Delphi applications. This library allows you to execute database queries in the background without freezing the UI, making your applications more responsive.
- Non-blocking UI: Execute database queries in background threads
- Thread safety: Proper synchronization and thread management
- Modern design: Optimized for recent Delphi versions (10.4+)
- Memory safety: Automatic cleanup and resource management
- Error handling: Comprehensive exception management
- Easy integration: Simple API for existing applications
- Download or clone this repository
- Add the
DFAsyncQuery.pas
unit to your project - Add
DFAsyncQuery
to your uses clause
procedure TForm1.SearchButtonClick(Sender: TObject);
var
QueryThread: TDFQueryThread;
begin
// Create and execute a query thread
QueryThread := DFQueryManager.CreateQueryThread(
ADOConnection1.ConnectionString,
'SELECT * FROM Customers WHERE LastName LIKE :LastName',
CreateParameters('LastName', '%' + edtSearch.Text + '%'),
DBGrid1,
ADOQuery1,
Self
);
// The thread automatically starts and updates the UI when complete
end;
// Helper function to create parameters
function TForm1.CreateParameters(const ParamName, ParamValue: string): TParameters;
begin
ADOQuery1.Parameters.Clear;
ADOQuery1.Parameters.CreateParameter(ParamName, ftString, pdInput, 50, ParamValue);
Result := ADOQuery1.Parameters;
end;
procedure TForm1.ExecuteMultipleQueries(Sender: TObject);
begin
// Execute first query
DFQueryManager.CreateQueryThread(
ADOConnection1.ConnectionString,
'SELECT * FROM Customers',
nil,
DBGrid1,
ADOQuery1,
Self
);
// Execute second query simultaneously
DFQueryManager.CreateQueryThread(
ADOConnection1.ConnectionString,
'SELECT * FROM Orders',
nil,
DBGrid2,
ADOQuery2,
Self
);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
// Clean up any running threads when closing the form
DFQueryManager.CleanupThreads;
end;
procedure TForm1.btnCancelQueryClick(Sender: TObject);
begin
// Cancel all active queries
DFQueryManager.CleanupThreads;
// Show current thread count
ShowMessage('Active Threads: ' + IntToStr(DFQueryManager.ThreadCount));
end;
The main thread class for executing asynchronous queries.
ID
: Unique identifier for the threadHasError
: Whether an error occurred during executionExceptionMessage
: Error message if HasError is true
Singleton manager that handles thread creation and lifecycle management.
CreateQueryThread
: Creates and starts a new query threadCleanupThreads
: Terminates all running threadsRemoveThread
: Removes a specific thread by IDThreadCount
: Returns the number of active threads
You can implement custom error handling by checking the thread's HasError property:
procedure TForm1.ExecuteQueryWithErrorHandling;
var
QueryThread: TDFQueryThread;
begin
QueryThread := DFQueryManager.CreateQueryThread(
ADOConnection1.ConnectionString,
'SELECT * FROM NonExistentTable', // This will cause an error
nil,
DBGrid1,
ADOQuery1,
Self
);
// The thread will automatically show an error dialog,
// but you can also implement custom error tracking or logging
end;
The component automatically handles cursor changes (hourglass during queries), but you can implement additional progress indication:
procedure TForm1.btnSearchClick(Sender: TObject);
begin
// Show progress panel
pnlProgress.Visible := True;
// Execute query
DFQueryManager.CreateQueryThread(
ADOConnection1.ConnectionString,
'SELECT * FROM LargeTable',
nil,
DBGrid1,
ADOQuery1,
Self
);
// You'll need to handle hiding the progress panel when the query completes
// This could be done using a custom event or timer
end;
- Delphi 10.4 or later
- VCL application
- ADO database components
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.