我創建了一個簡單的 webservie,但我遇到了應用程式記憶體增長的問題。
網路服務:
// Impl File
type
{ T_Service }
T_Service = class(TInvokableClass, I_Service)
public
function Convert(ReqAttach: TSOAPAttachment): TSOAPAttachment; stdcall;
end;
implementation
function T_Service.Convert(
ReqAttach: TSOAPAttachment): TSOAPAttachment;
var
memStream : TMemoryStream;
outStream : TMemoryStream;
try
ReqAttach.SaveToStream(memStream);
outStream.LoadFromFile('D:\Out.pdf');
RetAttach.SetSourceStream(outStream, soReference);
finally
memStream.Free;
end;
end;
initialization
{ Invokable classes must be registered }
InvRegistry.RegisterInvokableClass(T_Service);
end.
//Intf file
type
I_Service = interface(IInvokable)
['{69440128-AC9D-43CC-9A11-7B6B36F15D1E}']
function Convert(ReqAttach: TSOAPAttachment): TSOAPAttachment; stdcall;
end;
implementation
initialization
{ Invokable interfaces must be registered }
InvRegistry.RegisterInterface(TypeInfo(I_Service));
end.
我的客戶
procedure TClientForm.btnClick(Sender: TObject);
var
ReqAttach: TSOAPAttachment;
RespAttach: TSOAPAttachment;
Service: I_Service;
begin
ReqAttach := TSOAPAttachment.Create;
Service := unitIMyService.GetI_Service();
try
try
ReqAttach.SetSourceFile('D:\In.pdf');
RespAttach := Service.Convert(ReqAttach);
RespAttach.SaveToFile('D:\Resp.pdf');
finally
FreeAndNil(ReqAttach);
FreeAndNil(RespAttach);
end;
except
raise;
end;
end;
每次我執行 btnClick 動作 webservice 增長 0.2MB(Out.pdf 大小)。當然它回傳所需的檔案。
- GetI_Service 位于 WSDL 自動生成的檔案中
- 最終,網站將上傳的檔案在TSoapAttachment中進行轉換,并作為TSoapAttachment回傳。
uj5u.com熱心網友回復:
您正在泄漏,outStream因為您將它作為參考傳遞給RetAttach
RetAttach.SetSourceStream(outStream, soReference);
您需要改為使用soOwned作為Ownership引數。在這種情況下,記憶體管理outStream將轉移到RetAttach實體并自動處理。
RetAttach.SetSourceStream(outStream, soOwned);
除了重新引發例外之外,您還不必要地try...finally使用try...except它進行包裝。
try
try
...
finally
FreeAndNil(ReqAttach);
FreeAndNil(RespAttach);
end;
except
raise;
end;
您應該洗掉那個無用的try...except塊,因為以下代碼具有完全相同的效果。
try
...
finally
FreeAndNil(ReqAttach);
FreeAndNil(RespAttach);
end;
try...finally不處理例外它只是在finally塊中運行代碼而不管例外。該代碼運行后,例外將自動傳播到下一個例外處理程式。
您的代碼中的其他問題RespAttach是未初始化為 nil 并且FreeAndNil(RespAttach)如果例外發生在分配之前,您的呼叫可能正在懸空指標上運行。除此之外,這FreeAndNil也是多余的,因為您正在處理不會被重用的區域變數。
procedure TClientForm.btnClick(Sender: TObject);
var
ReqAttach: TSOAPAttachment;
RespAttach: TSOAPAttachment;
Service: I_Service;
begin
RespAttach := nil;
ReqAttach := TSOAPAttachment.Create;
try
Service := unitIMyService.GetI_Service();
ReqAttach.SetSourceFile('D:\In.pdf');
RespAttach := Service.Convert(ReqAttach);
RespAttach.SaveToFile('D:\Resp.pdf');
finally
ReqAttach.Free;
RespAttach.Free;
end;
end;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/400670.html
標籤:德尔福
