2013-02-25 3 views
3

У меня возникла интересная проблема.Delphi: CreateProcess + WaitForSingleObjects + DDE = 15 секундная задержка

У меня есть клиент DDE, который читает некоторое значение с сервера DDE. Когда я запускаю этого клиента из Delphi или с dblclick на exe, результат мгновенно появляется.

Но: когда я запустил его из потока 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. Exe?

Как WaitForS мастера могут замедлять вызов подпроцесса dde?

У вас есть идея решить эту проблему? Спасибо за любую информацию, ссылку, предложение!

ответ

8

DDE работает с сообщениями окна. Вызов WaitForSingleObject() может блокировать DDE по всей системе, если вызывающий поток получает любые сообщения DDE, например, из запущенного процесса, но не обрабатывает их. Таким образом, ваша 15-секундная задержка, вероятно, связана с тем, что ваш поток случайно блокирует операцию DDE, пока не истечет время на другом конце.

У вас есть несколько вариантов:

  1. иметь ваш нить вызов OleInitialize(), который будет молча обрабатывать вопросы DDE для вас.

  2. Использовать код ожидания MsgWaitForMultipleObjects() вместо WaitForSingleObject(), чтобы вы могли отправлять любые полученные сообщения во время ожидания.

  3. использование ShellExecuteEx() вместо CreateProcess(), указав SEE_MASK_NOASYNC флаг, поэтому операционная система знает, что вызывающий поток не имеет цикл обработки сообщений для обработки сообщений DDE.

+2

+1 Очень тонкий ответ –