Reputation: 27276
I have a TADOConnection
inside a thread. In the event that it fails to connect to the database (timeout), when closing the app, the thread is held up and it takes time until the attempt is finished before my app is able to close. I don't want to reduce the connection timeout of the connection, this isn't the issue. Is there any way I can forcefully abort the attempt to connect?
The TADOConnection
connects at the beginning of the thread execution and automatically reconnects repeatedly until success. Then, upon closing the app, if the database is failing to connect, the thread hangs until the connection attempt is finished (timed out).
EDIT
This is a sample of how the thread works:
procedure TMyThread.Init;
begin
CoInitialize(nil);
FDB:= TADOConnection.Create(nil);
FDB.LoginPrompt:= False;
FDB.ConnectionTimeout:= 5;
FDB.ConnectOptions:= coAsyncConnect;
end;
procedure TMyThread.Uninit;
begin
if FDB.Connected then
FDB.Connected:= False;
FDB.Free;
CoUninitialize;
end;
function TMyThread.Reconnect: Boolean;
begin
Result:= False;
if FDB.Connected then
FDB.Connected:= False;
FDB.ConnectionString:= FConnectionString;
try
FDB.Connected:= True; //How to abort?
Result:= True;
except
on e: exception do begin
//MessageDlg(e.Message, mtError, [mbOK], 0);
FDB.Connected:= False;
Result:= False;
end;
end;
end;
procedure TMyThread.Process;
begin
if Reconnect then begin //Once connected, keep alive in loop
while FActive do begin
if Terminated then Break;
if not Connected then Break;
//Do Some Database Work
end;
end else begin
//Log connection failure
end;
end;
procedure TMyThread.Execute;
begin
while not Terminated do begin
if FActive then begin
Init; //CoInitialize, create DB, etc.
try
while (FActive) and (not Terminated) do begin
try
Process; //Actual processing procedure
except
on e: exception do begin
//Record error to log
end;
end;
end;
finally
Uninit; //CoUninitialize, destroy DB, etc.
end;
end;
end;
end;
(Tried to include just relevant things to the question)
Upvotes: 3
Views: 2541
Reputation: 43659
First thing that comes to mind is to reduce connection's timeout. Why do you not want that? And why do you want to establish a connection when closing the application? Especially when you prefer to abort it when it takes more time than expected, why connect at all? Sounds like we could know more background info.
In the special case that you really need it on the condition that it connects quickly, ánd when this issue only applies to application's destruction, then I suggest not to wait for the thread to finish. Just do not free it, terminate the application, and let Windows kill the process including all its threads.
In the case that the connection does succeed, then this approach could backfire, so signal your main thread when the thread dóes connect, and postpone its termination by yet waiting for the thread. You may need another timeout for that again.
I suppose the OnWillConnect
event will occur every time the attempt to connect is made. Try returning EventStatus := esCancel
within its handler.
Upvotes: 2