Reputation: 3463
I experienced interesting problem.
I have a DDE client which is read some value from DDE server. When I start this client from Delphi, or with dblclick on the exe, the result instantly appears.
But: when I started it from Indy TCPServer's thread or from a master application, I got 15 seconds delay.
I used this code to start the subprocess:
function StartAndWaitProcess
(CmdLine : string='';
CmdShow : integer = SW_SHOW;
TimeOut : longint = -1) : Int64;
var
SInfo: TStartupInfo;
PInfo: TProcessInformation;
ExitCode : Cardinal;
begin
Result := -1;
FillChar(SInfo,SizeOf(TSTartupInfo),0);
with SInfo do begin
cb := sizeof(TStartupInfo);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := CmdShow;
end;
if not CreateProcess(nil, PChar(CmdLine),nil,nil,False,
NORMAL_PRIORITY_CLASS,nil,nil,SInfo,PInfo) then Exit;
if TimeOut > 0 then begin
if WaitForSingleObject(PInfo.hProcess, TimeOut) <> WAIT_OBJECT_0 then begin
TerminateProcess(PInfo.hProcess, 0);
Exit;
end
end else begin
WaitForSingleObject(PInfo.hProcess, INFINITE);
end;
GetExitCodeProcess(PInfo.hProcess, ExitCode);
Result := ExitCode;
end;
What is strange for me?
If I don't wait for the end, then the subprocess running with same performance as when I run it from normal application, so I got the result instantly and the windows disappears fast.
But if I wait for client's the end from the master, I got 15 sec delay.
I logged the client procedure times, and the 15 sec is passed with this dde procedure....
Delphi: DDE call from Indy TCPServer Thread
So I don't understand why the WaitForS causes speed problems on calling ddelcient.exe?
How the master's WaitForS can slowing down the subprocess' dde calls?
Do you have some idea to this problem? Thanks for any info, link, suggestion!
Upvotes: 3
Views: 1612
Reputation: 595837
DDE operates on window messages. Calling WaitForSingleObject()
can block DDE throughout the whole system if the calling thread receives any DDE messages, such as from the lauched process, but does not process them. So your 15s delay is likely due to your thread accidentally blocking a DDE operation until it times out on the other end.
You have a few choices:
Have your thread call OleInitialize()
, which will silently handle DDE issues for you.
Have your waiting code use MsgWaitForMultipleObjects()
instead of WaitForSingleObject()
so you can dispatch any received messages while waiting.
use ShellExecuteEx()
instead of CreateProcess()
, specifying the SEE_MASK_NOASYNC
flag, so the OS knows that the calling thread does not have a message loop to handle DDE messages.
Upvotes: 8