Reputation: 412
I am opening an ADOQuery asynchronously, and it works as expected, but any exceptions cause the application to hang. The exception does not get passed back to the main thread.
procedure TfrmMain.actRunExecute(Sender: TObject);
begin
ReportOpening := true;
with myADOQuery do begin
ExecuteOptions := [eoAsyncExecute, eoAsyncFetch, eoAsyncFetchNonBlocking];
OnFetchProgress := ADOQueryFetchProgress;
OnFetchComplete := ADOQueryFetchComplete;
try
Open;
except
on E: Exception do MessageDlg(E.Message, mtError, [mbOK], 0); //I expect a timeout here
end;
end;
end;
procedure TfrmMain.ADOQueryFetchComplete(DataSet: TCustomADODataSet; const Error: Error; var EventStatus: TEventStatus);
begin
ReportOpening := false;
end;
procedure TfrmMain.ADOQueryFetchProgress(DataSet: TCustomADODataSet; Progress, MaxProgress: Integer; var EventStatus: TEventStatus);
begin
TThread.Synchronize(nil, procedure()
begin
StatusBar1.Panels[1].Text := Format('Progress: %d of %d',[Progress, MaxProgress]);
end;
);
Application.ProcessMessages;
end;
Upvotes: 0
Views: 1137
Reputation: 11860
In async mode, you can catch the error in the OnExecuteComplete
event handler of your TADOConnection
object. You can use the EventStatus
and Error
objects to determine if there was a problem. Error.Description
will give you the error returned by the database server.
P.S.: please refrain from using Application.ProcessMessages
in your code as it is not needed since you are using async queries and it can lead to unforeseen event reentry scenarios.
Example:
procedure TForm1.ADOConnection1ExecuteComplete(Connection: TADOConnection; RecordsAffected: Integer; const Error: Error;
var EventStatus: TEventStatus; const Command: _Command; const Recordset: _Recordset);
begin
if EventStatus = esErrorsOccured then
begin
memo1.Lines.add(Error.Description);
// recover from error here
end;
end;
Upvotes: 1