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 は、ウィンドウ メッセージで動作します。呼び出しWaitForSingleObject()元のスレッドが、起動されたプロセスなどから DDE メッセージを受信するが、それらを処理しない場合、呼び出し元がシステム全体で DDE をブロックする可能性があります。したがって、15 秒の遅延は、スレッドが相手側でタイムアウトになるまで DDE 操作を誤ってブロックしたことが原因である可能性があります。

いくつかの選択肢があります:

  1. スレッドに を呼び出しOleInitialize()てもらいます。これにより、DDE の問題がサイレント モードで処理されます。

  2. MsgWaitForMultipleObjects()代わりに待機中のコードを使用して、待機WaitForSingleObject()中に受信したメッセージをディスパッチできるようにします。

  3. ShellExecuteEx()の代わりに を使用CreateProcess()して、フラグを指定しSEE_MASK_NOASYNCます。これにより、OS は、呼び出し元のスレッドに DDE メッセージを処理するメッセージ ループがないことがわかります。

于 2013-02-25T21:59:55.503 に答える