5

양식을 공개 할 때 AV가 있습니다. 압축하여 FireDAC 데이터 세트의 데이터를 원격 서버로 보낼 때 나타납니다. AV를 압축하여 TFDDataset의 데이터를 전송 한 후 AV를 수신 할 때 AV가 나타납니다.

내가 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 잎, 그리고 폼을 방출 할 때 AV를 발생시킵니다. 그러나 나는 잘못 될 수있는 것을 얻지 못한다.

추신 : @J ... 덕분에 전화 스택을 확인하는 것이 좋습니다. 문제의 원인을 발견했습니다. 이 호출 스택입니다 다음의 DataSnap 서버로 원격 호출을 실행하는 spActualizaDesglose TFDStoredProc의 매개 변수 AStream을 확보하려고 할 때

: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 

는 AV가 발생합니다.

전화를 변경 했으므로 원격 호출을 실행 한 후 원본 데이터 스트림을 해제하지 않습니다.

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; 

양식이 문제없이 출시되었지만 정확합니까?, 메모리 누수가 발생하지 않습니까?

감사합니다. the manual page에서

+0

안녕하세요 @Marc Guillot입니다. 오늘 저녁에이 문제를 재현 할 수 있는지 보겠습니다. 전에 데이터 크기는 어떤 종류입니까? 이 문제가 ServerMethods 스트림 반환 문제와 관련된 경우에 대해 묻고 있습니다. – MartynA

+0

Martyn에게 감사드립니다. 큰 스트림이있는 Datasnap의 문제와 관련이 없습니다. 단일 레코드 (수십 바이트) 만있는 경우에도 항상 발생합니다. –

+0

좋아, 나는 그것을 소용돌이 줄 것이다. CU 나중에 ... – MartynA

답변

7

다음 AsStream 속성을 설정

는 문자열/바이트 문자열/BLOB 데이터 유형 중 하나가 아닌 경우 ftStream하는 데이터 형식 속성을 설정합니다. 할당 된 TStream 객체는이 TFDParam이 소유하게됩니다. 명시 적으로 소유권을 제어하려면 SetStream 메서드를 사용하십시오.

강조 광산. 그래서 예, 매개 변수에 스트림을 할당하면 해당 스트림의 매개 변수 소유권이 주어지며 자체가 해제 될 때 스트림을 소유하게됩니다 (데이터 집합 구성 요소를 소유하는 양식에 의해 해제 될 때 데이터 집합에서 수행됨).

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

당신이 매개 변수에 대한 참조를 보유하고 매개 변수 객체가 그에게 두 번째 시간을 확보하려고 할 때 그것이 AV를 제기 오브젝트를 파괴 : 현재 스트림을 무료

.

+0

@J .... –

+1

@J ... 고맙습니다. : 잘 찾아 냈습니다. +1 – MartynA