在Delphi中没有响应,请避免使用ProcessMessages并使用线程

时间:2017-10-15 15:18:37

标签: multithreading delphi

我正在使用此过程来执行Comandline。我在网上找到了这段代码,除了一些细节外,它运行正常。我在一些论坛中读过不要使用ProcessMessages并将其放入线程中。

当我删除Application.ProcessMessages行时,它就会停止工作。 然后,如果我保留它,当它执行时我得到"Not responding"。在这种情况下你能帮我使用线程吗?

procedure ExecAndWait(const CommandLine: string);
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  FillChar(StartupInfo, SizeOf(StartupInfo), 0);
  StartupInfo.cb := SizeOf(TStartupInfo);
  StartupInfo.wShowWindow := SW_HIDE;
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;

  //UniqueString(CommandLine);

  if CreateProcess(nil, PChar(CommandLine), nil, nil, False,
    0, nil, nil, StartupInfo, ProcessInfo) then
  begin
    while WaitForSingleObject(ProcessInfo.hProcess, 10) > 0 do
    Application.ProcessMessages;
    CloseHandle(ProcessInfo.hProcess);
    CloseHandle(ProcessInfo.hThread);
  end
  else
    RaiseLastOSError;
end;
end.

procedure BuildThread;
var
  myThread: TThread;

begin
  // Create an anonymous thread that calls a method and passes in
  // the fetchURL to that method.
  myThread := TThread.CreateAnonymousThread(
    procedure
    begin
      ExecAndWait();
    end);
end;

我补充说:

procedure RunThread(const CommandLine: string);
var
  myThread: TThread;        
begin
  myThread := TThread.CreateAnonymousThread(
    procedure
    begin
      ExecAndWait(CommandLine);
    end). Start;
end;

1 个答案:

答案 0 :(得分:0)

不应引用匿名线程。您不应该尝试保留引用您的线程的局部变量。相反,您应该直接拨打Start来调用CreateAnonymousThread ...

procedure RunThread(const CommandLine: string);       
begin
  TThread.CreateAnonymousThread(
    procedure
    begin
      ExecAndWait(CommandLine);
    end).Start;
end;

此外,您应该在线程中使用Application.ProcessMessages尤其是Application是VCL的一部分,它不是线程安全的,因此打破了VCL多线程安全规则。即使情况并非如此,它仍然无用,因为它仅用于主UI线程。