我有一个客户端 - 服务器应用程序。
客户端(TCP Client)是一个Delphi应用程序,它向服务器发送命令(TCP Server,C ++ Builder应用程序)
它们都是用 Rad Studio XE2 编写的
服务器响应命令从SQL Server获取数据并将其发送到客户端
服务器使用 TClientDataSet 并将其保存到发送给客户端的 TMemoryStream 。
客户端还使用 TClientDataSet 并对从服务器接收的流调用 TClientDataSet.LoadFromStream()。
这很有效。
但是有一种情况是数据大小较大(约160 MB),其中有时“创建变量或安全数组时出错”在调用 TClientDataSet.LoadFromStream()在客户端。
服务器以这种方式将流发送到客户端:
//...
FContext->Connection->IOHandler->LargeStream = true;
FContext->Connection->IOHandler->Write(Stream, 0, true);
客户端以这种方式接收它:
AClient.IOHandler.LargeStream := True;
AClient.IOHandler.ReadStream(Stream, -1, False);
客户端收到后,会将流的位置更改为18 因为实际数据在18个字节后开始。然后它调用 TClientDataSet.LoadFromStream()。
//...
MemTable.LoadFromStream(Stream);
LoadFromStream()正在抛出“创建变体或安全数组的错误”。 但有些情况下它没有错误地工作。
有没有人有任何想法?
答案 0 :(得分:0)
基于Delphi 10的源代码,问题来自SafeArrayCreate
失败,很可能是因为EOutOfMemory异常。
SafeArrayCreate
尝试分配160MB的内存,这需要是连续的。你的进程的虚拟内存中可能没有足够大的“漏洞”来适应那么多的内存。在一个32位的过程中,我猜这不太可能。
缓解问题的一种方法可能是激活/ LARGEADDRESSAWARE标志。但这只会略微减少错误发生的可能性,并可能在未来很快再次出现。
其他选项包括:
编译为64位应用程序。
使用适当的数据库而不是内存数据集。