2012-01-16 26 views
7

Bir iş parçacığından XE/XE2'de SOAP kullanarak sorun yaşıyorum. (Ben eski Delphis ile test etmedim.) Ana iş parçacığında çalışan basit bir kod, Invalid pointer operation ile THTTPReqResp örneğini yok ederken çöküyor.Bir iş parçacığında THTTPReqResp bileşenini yok edemiyor

Bu, tam bir programdır. istisna _FreeMem çağrıda TObject.FreeInstance içinde yükseltilir

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. 

: Form btnTestClick olayı tetikler tek düğmesi bulunur.

procedure TObject.FreeInstance; 
begin 
    CleanupInstance; 
    _FreeMem(Self); 
end; 

bu soruna yol açan çağrı yığını Ben _ClassDestroy hiç denilen ve kod çöküyor neden :(birilerini Can neden, ne oluyor hiçbir fikrim yok

: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 

olduğunu lütfen a) yanlış yaptığımı açıkla ve b) kodumu düzelt?

+0

D2010 henüz CreateAnonymousThread adlı kullanıcı bulunmadı. Anonim olmayan biriyle çalışıyor. Anonim olmayan bir iş parçacığıyla kilitlenme yok. –

+0

Threading burada bir sorun değil (bence). Aynı şeyi OmniThreadLibrary (bu sorunu nasıl buldum) ile çöküyor. – gabr

+3

THttprio'nun belgelerinden "Nil (Delphi) veya NULL (C++) parametresiyle oluşturulduğunda, referans sayısı sıfıra düştüğünde otomatik olarak yok olur". Açıkça özgürsünüz. –

cevap

8

"Geçersiz işaretçi işlemi", geçerli belleği temsil etmeyen bir şeyi serbest bıraktığınız anlamına gelir. Bu bazen yığın veya yığın bozulmasını gösterir, ancak büyük olasılıkla serbest bırakılmış bir şeyi serbest bıraktığınızı gösterir.

_ClassDestroy'un çağrılması sürpriz değil. FHTTPReqResp, null değil, bu nedenle FreeAndNil, Free, Free numarasını Destroy olarak çağırır.

THTTPRIO nesnesinin, verdiğiniz THTTPReqResp sahipliğini satın aldığı anlaşılıyor. Bu durumda, çözüm basittir: kendiniz serbest bırakmayın.

+3

Haklısınız. Sadece FHTTPRIO'yu serbest bırakmak, FastMM4 FullDebugMode'u onayladı. Aptal kod mimarisi, bunu asla düşünmem! – gabr

+0

SOAP mimarisi "Yuck!" Ile dolu bir şey değil. anlar. Onunla bir yıl çalıştım. Benim en sevdiğim yönü, normalde WinInet'e bağlı olan ve bazı Windows sistemlerinde zaman aşımı/donma olanağına sahip olması. Indy tabanlı HTTPRIO aktarımına geçtiğinizde rastgele donmaları kaybedersiniz, ancak yaklaşık% 40'lık bir performans düşüşüne sahip olursunuz. İyi seçim. –

+0

Bu cevap için teşekkürler. Bir bellek sızıntısı sorunu yaşıyorum ve umarım bunu çözer. –

İlgili konular