我们有一个使用 INDY 的 Delphi 客户端服务器应用程序。客户端与服务器的单个 tIdTCPClient 连接是多线程的。客户端“理论上”是一个单线程。但实际上客户端上有多个线程,这就是我的问题所在。例如,考虑一个每分钟触发一次以从服务器获取数据的计时器。并考虑当用户在此计时器事件的同时运行命令时会发生什么。事实上,我的问题是由我们的“报表生成器”报表工具引起的,它(令人讨厌)坚持加载报表的每一页,这需要一段时间。该报告运行我们的“特殊”数据集,该数据集具有一次传输批量记录的缓存机制(因此多次调用服务器以获取所有数据)。同时,如果用户同时做其他事情,我们似乎得到了交叉数据。用户似乎取回了用于报告的数据。
顺便说一句,这个错误非常罕见,但对于拥有世界上最慢互联网的特定客户来说,这种情况要少得多(幸运的是,我现在有一个测试环境)。
所以在客户端我有这样的代码......
procedure DoCommand(MyIdTCPClient:tIdTCPClient; var DATA:tMemoryStream);
var
Buffer: TBytes;
DataSize: Integer;
CommsVerTest: String;
begin
//Write Data
MyIdTCPClient.IOHandler.Write(DATA.Size);
MyIdTCPClient.IOHandler.Write(RawToBytes(Data.Memory^,DataSize));
//Read back 6 bytes CommsVerTest should always be the same (ie ABC123)
SetLength(Buffer,0); //Clear out buffer
MyIdTCPClient.IOHandler.ReadBytes(Buffer,6);
CommsVerTest:=BytesToString(Buffer);
if CommsVerTest<>'ABC123' then
raise exception.create('Invalid Comms'); //It bugs out here in rare cases
//Get Result Data Back from Server
DataSize:=MyIdTCPClient.IOHandler.ReadLongInt;
Data.SetSize(DataSize); //Report thread is stuck here
MyIdTCPClient.IOHandler.ReadBytes(Buffer,DataSize);
end;
现在,当我调试它时,我可以确认当此过程中间有两个线程时它会出错。主线程在异常处停止。并且报告线程在同一过程中被卡在其他地方。
所以,在我看来,我需要使线程上面的过程安全。我的意思是,如果用户想要做某事,他们只需要等到报告线程完成。
Arrrgh,我认为我的客户端应用程序是单线程的,用于向服务器发送数据!
我认为使用 TThread 是行不通的——因为我无法访问 Report Builder 中的线程。我想我需要一个 tCriticalSection。
我想我需要制作应用程序,以便一次只能由一个线程运行上述过程。其他线程必须等待。
有人请帮助语法。