我們有一個使用INDY的Delphi客戶端服務器應用程序。客戶端有一個到多線程服務器的tIdTCPClient連接。客戶是「理論上」的單一線程。但實際上客戶端上有多個線程,這是我的問題所在。例如,想象一下每分鐘觸發一次從服務器獲取數據的計時器。並且考慮一下當用戶在這個計時器事件的同時運行一個命令時會發生什麼。事實上,我的問題是由我們的「報告生成器」報告工具引起的,(令人煩惱地)堅持要加載報告的每一頁,這需要一段時間。該報告運行我們的「特殊」數據集,該數據集具有緩存機制來一次傳輸批量記錄(因此多次調用服務器以獲取所有數據)。同時,如果用戶在同一時間做了其他事情,我們似乎正在越過數據。用戶似乎收回了用於報告的數據。帶有定時器事件和其他多線程客戶端事件的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。
我想我需要使應用程序,以便上述過程一次只能由一個線程運行。其他線程必須等待。
有人請幫忙的語法。