2012-01-16 6 views
7

मुझे थ्रेड से XE/XE2 में SOAP का उपयोग करने में समस्याएं आ रही हैं। (मैंने पुराने डेल्फी के साथ इसका परीक्षण नहीं किया था।) Invalid pointer operation के साथ THTTPReqResp उदाहरण को नष्ट करते समय मुख्य थ्रेड में काम करने वाला एक साधारण कोड क्रैश हो जाता है।थ्रेड में THTTPReqResp घटक को नष्ट नहीं कर सकता

यह एक पूरा कार्यक्रम है।

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. 

अपवाद _FreeMem फोन पर TObject.FreeInstance में उठाया जाता है: प्रपत्र केवल एक बटन जो btnTestClick ईवेंट ट्रिगर होता है।

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

कॉल स्टैक इस समस्या के लिए अग्रणी

: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 

है मैं बिल्कुल पता नहीं क्या, हो रहा है क्यों _ClassDestroy सब पर कहा जाता है और यही कारण है कि कोड दुर्घटनाओं :(किसी सकते हैं कृपया ए) समझाओ कि मैं क्या गलत कर रहा हूं और बी) मेरे कोड को ठीक करें?

+0

डी 2010 में अभी तक CreateAnonymousThread नहीं है। अब गैर-अज्ञात के साथ प्रयास कर रहा है। गैर-अज्ञात धागे के साथ कोई क्रैश नहीं। –

+0

थ्रेडिंग कोई मुद्दा नहीं है (मुझे लगता है)। यह OmniThreadLibrary के साथ दुर्घटनाग्रस्त हो जाता है (जो मुझे यह समस्या मिली थी)। – gabr

+3

थेटप्रियो के प्रलेखन से "जब यह एक शून्य (डेल्फी) या न्यूल (सी ++) पैरामीटर के साथ बनाया जाता है, तो जब संदर्भ गणना शून्य पर गिर जाती है तो यह स्वतः नष्ट हो जाएगी"। आप इसे स्पष्ट रूप से मुक्त कर रहे हैं। –

उत्तर

8

"अमान्य सूचक ऑपरेशन" का अर्थ है कि आप कुछ ऐसी चीज मुक्त कर रहे हैं जो वैध स्मृति का प्रतिनिधित्व नहीं करता है। यह कभी-कभी ढेर या ढेर भ्रष्टाचार को इंगित कर सकता है, लेकिन यह अधिक संभावना है कि आप कुछ ऐसा मुक्त कर रहे हैं जो पहले से ही मुक्त हो चुका है।

इसमें कोई आश्चर्य की बात नहीं है कि _ClassDestroy कहा जाता है। FHTTPReqResp गैर-शून्य है, इसलिए FreeAndNil पर Free पर कॉल करें, FreeDestroy पर कॉल करें।

ऐसा लगता है कि आपकी THTTPRIO ऑब्जेक्ट THTTPReqResp का स्वामित्व प्राप्त करता है जो आप इसे देते हैं। यदि ऐसा है, तो समाधान सरल है: इसे स्वयं मुक्त न करें।

+3

आप सही हैं। केवल FHTTPRIO को मुक्त करना FastMM4 FullDebugMode पुष्टि के रूप में दोनों को नष्ट कर देता है। बेवकूफ कोड वास्तुकला, मैं कभी इसके बारे में नहीं सोचूंगा! – gabr

+0

एसओएपी आर्किटेक्चर कुछ भी नहीं है लेकिन "यक!" से भरा हुआ है क्षणों। मैंने इसके साथ काम करने में एक साल बिताया। इसका मेरा सबसे पसंदीदा पहलू यह तरीका है कि यह सामान्य रूप से WinInet पर निर्भर करता है, जो छोटी है और कुछ विंडोज सिस्टम पर टाइमआउट/फ्रीज-अप है। जब आप इंडी-आधारित HTTPRIO परिवहन पर स्विच करते हैं तो आप यादृच्छिक फ्रीज खो देते हैं, लेकिन आपको लगभग 40% के प्रदर्शन में एक समग्र गिरावट मिलती है। अच्छा चुनाव। –

+0

इस उत्तर के लिए धन्यवाद। मुझे स्मृति रिसाव की समस्या है और उम्मीद है कि यह हल हो जाएगा। –