5

ich einen AV habe, wenn ein Formular Freigabe, erscheint es, wenn ich komprimiere und eine FireDAC Dataset der Daten an einen entfernten Server senden.AV, wenn ein Formular nach dem Komprimieren und Senden eines TFDDataset Data Freigabe

Dies ist der Code verwende ich die TFDDataset der Daten zu komprimieren:

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; 

Und das ist der Code, die komprimierten Daten an den Remote-Aufruf (DataSnap) zu senden.

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; 

Dieser Code lässt etwas instabil, wahrscheinlich die TFDDataset qryFacturacion_Desglose, und wirft eine AV, wenn Sie das Formular veröffentlichen. Aber ich verstehe nicht, was möglich sein könnte.

PS: Dank @J ... Vorschlag der Call Stack zu überprüfen Ich habe die Ursache des Problems gefunden. Dies ist die Call Stack:

: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 

Das AV tritt auf, wenn versucht, die Parameter AStream des spActualizaDesglose TFDStoredProc zu befreien, die den Remote-Aufruf des DataSnap-Server ausführt.

Ich habe den Anruf geändert, so dass es nicht befreit nicht den ursprünglichen Datenstrom nach dem Remote-Aufruf ausgeführt wird.

Jetzt ist das Formular ohne Probleme freigegeben, aber ist das korrekt?, Werde ich nicht ein Speicherleck haben?.

Vielen Dank.

+0

Hallo @Marc Guillot. Ich werde vielleicht sehen, ob ich dieses Problem heute Abend reproduzieren kann. Bevor ich das mache, welche Art von Größe ist Ihr 'Data' Stream? Ich frage, ob dies mit den ServerMethods-Stream-zurückkehrenden Problemen zusammenhängt. – MartynA

+0

Vielen Dank Martyn, das hängt nicht mit dem Problem auf Datasnap mit großen Streams zusammen. Es passiert immer, auch wenn nur ein einzelner Datensatz vorhanden ist (einige Dutzend Bytes). –

+0

Ok, ich werde es einen Wirbel geben. CU später ... – MartynA

Antwort

7

Von the manual page:

die AsStream Eigenschaft festlegen, setzt die Eigenschaft Datatype auf ftStream, wenn es nicht eine der Zeichenkette/Bytestring/BLOB-Datentypen ist. Das zugewiesene TStream-Objekt gehört diesem TFDParam. Um die Eigentumsrechte explizit zu steuern, verwenden Sie die SetStream-Methode.

Schwerpunkt meiner. Also ja, gibt den Strom an den Parameter Zuweisung der Parameter Eigentum an diesem Strom, und es wird verantwortlich für die Freigabe es, wenn sie sich befreit ist (was von der Datenmenge erfolgt, wenn sie von der Form befreit wird, die die Datenmengenkomponente besitzt).

Wenn Sie den Stream frei hier:

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

Sie das Objekt zu zerstören, dass der Parameter eine Referenz hält und es stellt sich ein AV, wenn der Parameter Objekt ein zweites Mal zu befreien versucht.

+0

Danke @J .... –

+1

@J ...: Gut entdeckt, +1 – MartynA

Verwandte Themen