Tengo problemas utilizando SOAP en XE/XE2 de un hilo. (No lo probé con Delphis antiguo). Un código simple que funciona en el hilo principal se bloquea al destruir la instancia THTTPReqResp con Invalid pointer operation
.no puede destruir componente THTTPReqResp en un hilo
Este es el programa completo. El formulario contiene sólo un botón que desencadena evento btnTestClick:
unit Unit79;
interface
uses
SysUtils, Forms, Classes, Controls, StdCtrls, ComObj,
ActiveX, InvokeRegistry, SOAPHTTPTrans, Rio, SOAPHTTPClient;
type
TForm79 = class(TForm)
btnTest: TButton;
procedure btnTestClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form79: TForm79;
implementation
{$R *.dfm}
procedure TForm79.btnTestClick(Sender: TObject);
begin
TThread.CreateAnonymousThread(
procedure
var
FHTTPReqResp: THTTPReqResp;
FHTTPRIO: THTTPRIO;
begin
if CoInitializeEx(NIL, COINIT_MULTITHREADED or COINIT_SPEED_OVER_MEMORY) = S_OK then try
FHTTPReqResp := THTTPReqResp.Create(nil);
with FHTTPReqResp do begin
Name := 'HTTPReqResp1';
UseUTF8InHeader := True;
InvokeOptions := [soIgnoreInvalidCerts, soAutoCheckAccessPointViaUDDI];
WebNodeOptions := [];
end;
FHTTPRIO := THTTPRIO.Create(nil);
with FHTTPRIO do begin
Name := 'HTTPRIO1';
HTTPWebNode := FHTTPReqResp;
end;
//
FreeAndNil(FHTTPRIO);
FreeAndNil(FHTTPReqResp); //<-- crashes here
finally CoUninitialize; end;
end
).Start;
end;
end.
La excepción se lanza en TObject.FreeInstance en la llamada _FreeMem.
procedure TObject.FreeInstance;
begin
CleanupInstance;
_FreeMem(Self);
end;
La pila de llamadas que conduce a este problema es
:75bab9bc KERNELBASE.RaiseException + 0x58 System.TObject.FreeInstance System.ErrorAt(2,$4052E1) System.Error(reInvalidPtr) System.TObject.FreeInstance System._ClassDestroy(???) Soap.SOAPHTTPTrans.THTTPReqResp.Destroy System.TObject.Free frmMain.TMainForm.btnTestClick$4934$ActRec.$0$Body System.Classes.TAnonymousThread.Execute System.Classes.ThreadProc($F83530) System.ThreadWrapper($F51050) :76a4339a kernel32.BaseThreadInitThunk + 0x12 :77b59ef2 ntdll.RtlInitializeExceptionChain + 0x63 :77b59ec5 ntdll.RtlInitializeExceptionChain + 0x36
no tengo absolutamente ninguna idea de lo que está pasando, por qué _ClassDestroy se llama en absoluto y por qué el código se bloquea :(Puede alguien por favor a) explicar lo que estoy haciendo mal yb) arreglar mi código?
D2010 no tiene CreateAnonymousThread todavía. Probando con no anónimo ahora. No se bloquea con un hilo no anónimo. –
Enhebrar no es un problema aquí (creo). Se bloquea lo mismo con OmniThreadLibrary (que fue la forma en que encontré este problema). – gabr
De la documentación de THttprio "Cuando se crea con un parámetro nil (Delphi) o NULL (C++), se autodestruirá cuando el recuento de referencias caiga a cero". Lo estás liberando explícitamente. –