2017-10-15 167 views
-1

我正在使用此过程来执行Comandline。我在网上找到了这段代码,除了一些细节外,它工作正常。我在一些论坛上看过不要使用ProcessMessages并将其放入一个线程中。在Delphi中没有响应,请避免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; 
+0

你的问题是什么? –

+0

@DavidHeffernan,基本上我想知道如何防止“不响应”显示。我在线阅读,他们建议将CreateProcess放入线程 –

+0

创建一个线程以等待进程句柄。当它被发信号时,通知UI线程。 –

回答

0

匿名线程并不意味着被引用。你不应该试图保留引用你的线程的局部变量。相反,你应该直接从一个线程中调用在线与调用CreateAnonymousThreadStart ...

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

此外,你应该使用Application.ProcessMessages特别Application是VCL的一部分,它不是线程安全的,因此打破了VCL多线程安全规则。即使不是这样,它仍然是无用的,因为它只用于主UI线程。

相关问题