I needed to add some threads to perform certain processes in the background. This thread accesses the methods of a WebService and also performs operations on the database.
I create all the objects I need to use in this thread within itself to avoid concurrent access with components outside of it. As IBDatabase
and IBTransaction
(use IBX components).
So my thread looks something like this:
TThreadAtualizarDados = class(TThread)
private
FIBDatabase: TIBDatabase;
FIBTransaction: TIBTransaction;
public
constructor Create(AIBDatabase: TIBDatabase); reintroduce;
destructor Destroy; override;
procedure Execute; override;
end;
As I said, everything I need to use in the thread I instantiate in itself.
constructor TThreadAtualizarDados.Create(AIBDatabase: TIBDatabase);
begin
inherited Create(false);
FreeOnTerminate := true;
// conexão com o banco de dados
FIBDatabase := TIBDatabase.Create(nil);
FIBDatabase.LoginPrompt := false;
FIBDatabase.DatabaseName := AIBDatabase.DatabaseName;
FIBDatabase.Params.Text := AIBDatabase.Params.Text;
// controle transacional
FIBTransaction := TIBTransaction.Create(nil);
FIBTransaction.DefaultDatabase := FIBDatabase;
FIBDatabase.DefaultTransaction := FIBTransaction;
end;
The processes I want it to perform are successful until the execution is complete.
destructor TThreadAtualizarDados.Destroy;
begin
inherited;
if FIBTransaction.Active then
FIBTransaction.Commit;
// Comentados porque está causando erro
//
// FIBDatabase.Free;
// FIBTransaction.Free;
end;
The lines that terminate the connection and the transaction are commented out because if they are executed, a certain time after the thread termination (output of the Destroy
method) is generated an error.
Error Message:
Program.exe faulted with message: 'application-defined exception (code 0xc000041d) at 0x77071a91'.
What does not feature Access Violation .
What might be causing this error, and what to do to solve it?
Adding More Information:
The thread is instantiated this way:
procedure TFrmAtualizaDados.p_Iniciar_Atualizacao;
begin
TThreadAtualizarDados.Create(Dm.IdbIntsys);
end;
That is, no external processing is done on the thread. I'm not passing her reference to any variable so that I could be finalizing it manually, or anything else. Since I set the parameter of it to execute as soon as I instantiated inherited Create(false);
and had it destroy itself automatically after finishing its method Execute
, with FreeOnTerminate := true;
, then just instantiate passing the parameters and let it work.
In addition, I have even other classes in the thread that instantiate, such as TStringList
and TList
, which do not give problems, only the instances of the database components generate problems if they are released from memory ( .Free
). / p>
Another detail is that the error message is triggered only when I switch from the application to Delphi in debug mode.
Of course, the " Stop on Delphi Exceptions " option in Debuger Options "is enabled .