【发布时间】:2021-12-28 11:14:57
【问题描述】:
我创建了一个简单的 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返回。
【问题讨论】:
-
您的代码无法编译。
T_Service.Convert不完整,因此可能存在其他问题,但您有泄漏,因为您从不释放 outStream 并且您应该使用RetAttach.SetSourceStream(outStream, soOwned);来处理不再需要时释放该流。 -
同样用
raise将try...finally包裹在try..except中是没有意义的。try...finally不用于处理异常,它将传播到下一个异常处理程序。try..finally只在 finally 块中运行代码,不管异常 -
@DalijaPrasnikar 这就是重点。当我发布 outStream:
finally outStream.Free end;然后我在客户端中没有返回的数据,并且我有一个异常“访问冲突在...”。对于 TSoapAttachment 客户端应该释放内存。在 Soap.InvokeRegistry.pas 理论上它的集合:'RemClassRegistry.RegisterXSClass(TSOAPAttachment, ...实际上它不起作用。try...try..为简单起见,我删除了错误处理。 -
是的,你不能手动释放
outStream,这就是为什么我说你需要使用soOwned而不是soReference所以outStream内存将由RetAttach处理跨度>
标签: delphi