2013-02-25 130 views
3

我遇到了一个有趣的问题。Delphi:CreateProcess + WaitForSingleObjects + DDE = 15秒延迟

我有一个从DDE服务器读取一些值的DDE客户端。 当我从Delphi启动这个客户端时,或者在exe上使用dblclick时,结果立即出现。

但是:当我从Indy TCPServer的线程或主应用程序启动它时,我得到了15秒的延迟。

我用这个代码启动子:

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; 

对我来说有什么奇怪?

如果我不等待结束,那么子程序运行时的性能与我在正常应用程序中运行时相同,因此我立即得到结果,并且窗口消失得很快。

但是,如果我等待客户端的主人,我得到了15秒的延迟。

我登录客户端程序的时间,而15秒的传递与此DDE程序....

Delphi: DDE call from Indy TCPServer Thread

所以我不明白为什么WaitForS导致上调用ddelcient速度问题。可执行程序?

大师的WaitForS如何减缓子进程的dde调用?

你对这个问题有一些想法吗?感谢您的任何信息,链接,建议!

回答

8

DDE对窗口消息进行操作。调用WaitForSingleObject()可以在整个系统中阻塞DDE,如果调用线程收到任何DDE消息,例如来自激活的进程但不处理它们。所以15秒的延迟可能是由于你的线程意外地阻塞了DDE操作,直到它在另一端超时。

您有几种选择:

  1. 让你的线程调用OleInitialize(),这将默默地为你处理DDE问题。

  2. 让你的等待代码使用MsgWaitForMultipleObjects()而不是WaitForSingleObject(),这样你就可以在等待时发送任何收到的消息。

  3. 的使用ShellExecuteEx()代替CreateProcess(),指定SEE_MASK_NOASYNC标志,让OS知道调用线程没有消息循环来处理DDE消息。

+2

+1非常好的答案 – 2013-02-25 22:14:57