durumdara
durumdara

Reputation: 3463

Delphi: CreateProcess + WaitForSingleObjects + DDE = 15 second delay

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

Answers (1)

Remy Lebeau
Remy Lebeau

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:

  1. Have your thread call OleInitialize(), which will silently handle DDE issues for you.

  2. Have your waiting code use MsgWaitForMultipleObjects() instead of WaitForSingleObject() so you can dispatch any received messages while waiting.

  3. 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

Related Questions