3

我遇到了有趣的问题。

我有一个从 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 秒。

我记录了客户端过程的时间,这个 dde ​​过程通过了 15 秒....

Delphi:来自 Indy TCPServer 线程的 DDE 调用

所以我不明白为什么 WaitForS 在调用 ddelcient.exe 时会导致速度问题?

主进程的 WaitForS 如何减慢子进程的 dde ​​调用速度?

你对这个问题有什么想法吗?感谢您提供任何信息,链接,建议!

4

1 回答 1

8

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

你有几个选择:

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

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

  3. 使用ShellExecuteEx()而不是CreateProcess()指定SEE_MASK_NOASYNC标志,因此操作系统知道调用线程没有消息循环来处理 DDE 消息。

于 2013-02-25T21:59:55.503 回答