5

मेरे पास एक फॉर्म जारी करते समय एक एवी है, ऐसा लगता है जब मैं एक दूरस्थ सर्वर पर एक फायरडीएसी डेटासेट डेटा को संपीड़ित और भेजता हूं।एवी एक टीएफडी डेटासेट के डेटा को संपीड़ित करने और भेजने के बाद एक फॉर्म जारी करते समय

इस कोड मैं TFDDataset की डेटा सेक करने के लिए उपयोग है:

function CompressDataset(Dataset: TFDDataset): TMemoryStream; 
var Data: TMemoryStream; 
    Compress: TZCompressionStream; 
begin 
    Result := TMemoryStream.Create; 
    Data := TMemoryStream.Create; 
    try 
    Compress := TZCompressionStream.Create(Result); 
    Dataset.SaveToStream(Data, TFDStorageFormat.sfBinary); 
    Data.Position := 0; 
    Compress.CopyFrom(Data, Data.Size); 
    finally 
    Data.Free; 
    Compress.Free; 
    end; 
    Result.Position := 0; 
end; 

और इस दूरदराज के कॉल (Datasnap) करने के लिए कि संकुचित डेटा भेजने के लिए कोड है।

procedure TfrmRentFacturacion_Facturar.btnSendDesgloseClick(Sender: TObject); 
var Stream: TMemoryStream; 
begin 
    if qryFacturacion_Desglose.State = dsEdit then qryFacturacion_Desglose.Post; 

    Stream := CompressDataset(qryFacturacion_Desglose); 
    try 
    spActualizaDesglose.ParamByName('AStream').AsStream := Stream; 
    spActualizaDesglose.ExecProc; 
    finally 
    Stream.Free; 
    end; 
end; 

इस कोड को कुछ अस्थिर, सबसे शायद TFDDataset qryFacturacion_Desglose छोड़ देता है, और जब प्रपत्र जारी एक ए वी उठाती है। लेकिन मुझे यह नहीं मिलता कि क्या गलत हो सकता है।

पीएस: कॉल स्टैक की जांच करने के लिए @ जे ... सुझाव के लिए धन्यवाद मुझे समस्या का स्रोत मिला है। यह कॉल स्टैक है:

:000000000040E735 TObject.Free + $15 
:00000000007F1123 TParamObject.Destroy + $43 
:000000000041A155 TInterfacedObject._Release + $55 
:000007FEFF2211CE ; C:\Windows\system32\oleaut32.dll 
:0000000000459DAB VarClearDeep + $1B 
:0000000000459E6B @VarClear + $1B 
:0000000000459E7D @VarClr + $D 
:00000000004149F4 @VarClr + $14 
:0000000000414ACC @FinalizeArray + $BC 
:00000000004162F1 @DynArrayClear + $61 
:0000000000414B58 @FinalizeArray + $148 
:0000000000414985 @FinalizeRecord + $75 
:000000000040E82E TObject.CleanupInstance + $4E 
:000000000040E450 TObject.FreeInstance + $10 
:000000000040F1C1 @ClassDestroy + $11 
:000000000051ED43 TCollectionItem.Destroy + $43 
:000000000040E738 TObject.Free + $18 
:000000000051F40A TCollection.Clear + $5A 
:000000000051F1CD TCollection.Destroy + $2D 
:000000000084A858 TFDParams.Destroy + $88 
:0000000000838FD8 FDFree + $18 
:000000000084A8BB TFDParams.RemRef + $2B 
:0000000000B8C907 TFDCustomCommand.Destroy + $57 
:000000000040E738 TObject.Free + $18 
:00000000005419F3 TComponent.DestroyComponents + $93 
:000000000054117F TComponent.Destroy + $2F 
:0000000000B92A66 TFDCustomTableAdapter.Destroy + $86 
:0000000000B9BE02 TFDRdbmsDataSet.Destroy + $C2 
:000000000040E738 TObject.Free + $18 
:00000000005419F3 TComponent.DestroyComponents + $93 
:000000000054117F TComponent.Destroy + $2F 
:00000000006039C2 TControl.Destroy + $192 
:000000000060AA91 TWinControl.Destroy + $1B1 
:0000000000797273 TScrollingWinControl.Destroy + $73 
:0000000000798EB7 TCustomForm.Destroy + $1E7 
:000000000040E738 TObject.Free + $18 
:00000000007A1389 TCustomForm.CMRelease + $9 
:000000000040EE81 TObject.Dispatch + $41 
:0000000000607D56 TControl.WndProc + $386 
:000000000060EC07 TWinControl.WndProc + $8E7 
:000000000079ADB0 TCustomForm.WndProc + $910 
:000000000060DE4C TWinControl.MainWndProc + $2C 
:0000000000545056 StdWndProc + $26 
:00000000777D9BBD ; C:\Windows\system32\USER32.dll 
:00000000777D98C2 ; C:\Windows\system32\USER32.dll 
:00000000007A8E84 TApplication.ProcessMessage + $134 
:00000000007A8EF8 TApplication.HandleMessage + $18 
:00000000007A9364 TApplication.Run + $F4 
Impuestos.Impuestos 
:00000000776B59CD ; C:\Windows\system32\kernel32.dll 
:00000000778EA561 ; ntdll.dll 

ए वी तब होता है जब spActualizaDesglose TFDStoredProc के पैरामीटर AStream कि Datasnap सर्वर से दूरस्थ कॉल निष्पादित करता है मुक्त करने के लिए कोशिश कर रहा।

मैंने कॉल बदल दिया है, इसलिए यह दूरस्थ कॉल निष्पादित करने के बाद मूल डेटा स्ट्रीम को मुक्त नहीं करता है।

procedure TfrmRentFacturacion_Facturar.btnSendDesgloseClick(Sender: TObject); 
    var Stream: TMemoryStream; 
    begin 
     if qryFacturacion_Desglose.State = dsEdit then qryFacturacion_Desglose.Post; 

     Stream := CompressDataset(qryFacturacion_Desglose); 
     spActualizaDesglose.ParamByName('AStream').AsStream := Stream; 
     spActualizaDesglose.ExecProc; 
    end; 

अब प्रपत्र मैं एक स्मृति रिसाव नहीं होगा समस्याओं के बिना जारी किया गया है, लेकिन यह सही है?,?।

धन्यवाद।

+0

हाय @ मर्क गिलोट। मैं शायद देखूंगा कि क्या मैं इस शाम को इस समस्या को पुन: पेश कर सकता हूं। इससे पहले कि, आपकी 'डेटा' स्ट्रीम किस प्रकार का आकार है? मैं इस मामले में पूछ रहा हूं कि यह सर्वरमाइड्स स्ट्रीम-रिटर्निंग समस्या से संबंधित है। – MartynA

+0

धन्यवाद बहुत मार्टिन, यह बड़ी धाराओं के साथ डेटासेट पर समस्या से संबंधित नहीं है। यह हमेशा होता है, भले ही केवल एक रिकॉर्ड (बाइट्स के कुछ दर्जन) हों। –

+0

ठीक है, मैं इसे एक भंवर दे दूंगा। बाद में सीयू ... – MartynA

उत्तर

7

the manual page से:

AsStream गुण को सेट अगर यह चरित्र स्ट्रिंग/बाइट स्ट्रिंग/ब्लॉब डेटा प्रकार से एक नहीं है ftStream लिए डेटा प्रकार गुण निर्धारित करता है। असाइन किए गए टीस्ट्रीम ऑब्जेक्ट का स्वामित्व इस टीएफडीपीराम के पास होगा। स्वामित्व को स्पष्ट रूप से नियंत्रित करने के लिए, सेटस्ट्रीम विधि का उपयोग करें।

जोर मेरा। तो हाँ, पैरामीटर को स्ट्रीम असाइन करना उस स्ट्रीम के पैरामीटर स्वामित्व को देता है और जब इसे स्वयं मुक्त किया जाता है तो इसे मुक्त करने के लिए ज़िम्मेदार हो जाता है (जो डेटासेट द्वारा किया जाता है जब इसे डेटासेट घटक के मालिक द्वारा मुक्त किया जाता है)।

आप धारा यहाँ मुक्त कब:

Stream := CompressDataset(qryFacturacion_Desglose); 
try 
    spActualizaDesglose.ParamByName('AStream').AsStream := Stream; 
    spActualizaDesglose.ExecProc; 
finally 
    Stream.Free; 
end; 

आप उद्देश्य यह है कि पैरामीटर के लिए एक संदर्भ रखा है और जब पैरामीटर वस्तु यह दूसरी बार मुक्त करने की कोशिश करता है कि यह एक ए वी को जन्म देती है को नष्ट करने कर रहे हैं।

+0

धन्यवाद @ जे .... –

+1

@ जे ...: अच्छी तरह से देखा गया, +1 – MartynA

संबंधित मुद्दे