我正在寻找Delphi中CreateProcess的快速替代方法来在exe中执行某些计算,包括XML中的几个返回值。 目前,我正在使用某些参数调用C#-exe。其中一个电话约需要。 0.5s - 这是方式昂贵,因为这个exe需要被调用几百次(不幸的迭代调用,即多线程不会加速工作)。
我当前的代码看起来像这样(找到解决方案来获取StackOverflow上的exe somwhere的控制台输出)。
IsExecutable := CreateProcess(
nil,
PChar(WorkDir + Exe + CommandLine),
nil,
nil,
True,
HIGH_PRIORITY_CLASS,
nil,
nil,
StartupInfo,
ProcessInformation);
CloseHandle(StdOutPipeWrite);
if IsExecutable then
try
repeat
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
if BytesRead > 0 then
begin
Buffer[BytesRead] := #0;
Result := Result + Buffer;
end;
until not WasOK or (BytesRead = 0);
WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
finally
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
end
不过,我对Delphi不是很好 - 实际上,我觉得“我不知道我在做什么”的狗咪模因......
答案 0 :(得分:8)
创建新流程非常昂贵。没有其他方法可以使用CreateProcess
。这里没有快速修复。没有神奇的按钮可以让流程创建速度超快。
解决问题的方法是停止创建一个新流程。在您的流程中执行此任务。
答案 1 :(得分:3)
您是否每次都需要创建新流程?或者你可以重复使用相同的实例吗? 您可以使用一些低级控制台输入/输出管道(您的代码看起来就像现在尝试这样做:)),或者您可以使用某种IPC(互斥+共享内存,在两个进程之间复制数据) ),或者您可以通过TCP / IP进行通信来使用更多的n层(或客户端/服务器)方法(RemObjects SDK非常适合这个,有.Net和Delphi库,通过TCP / IP进行通信,或者Windows消息,命名管道等)。然而,最后一种方法由于抽象而增加了一些延迟/开销,但是比在.Net和Delphi中实现双方更容易使用(这不是那么困难)。
答案 2 :(得分:3)
与David wrote和André wrote一样,您无法更改此内容。
这是真正的big differences between Windows and Linux之一。 Windows中的CreateProcess
非常昂贵,而Linux中的fork
便宜。另一方面,Linux fork
之后通常是exec
,价格昂贵。这就是.NET introduced the AppDomain
which is faster。
您可以通过几个方向将.NET代码集成到您的流程中,例如Arnaud wrote。
您可以做的另一件事是在Delphi进程和.NET进程之间进行IPC(例如使用命名管道),并让.NET进程为每个请求使用AppDomains。
答案 3 :(得分:1)
这里很慢的是创建一个新进程,并且每次运行可执行文件时都会启动整个.Net框架进程。
为了获得最佳性能,最好将C#进程公开为COM,然后直接从Delphi中调用它。
在这种情况下,通过TCP / IP进行远程连接是不值得的,我想。几年前,我在本地机器上使用RemObjects的速度实验很糟糕。
您需要的是致电COM互操作,您可能对以下内容感兴趣:
Delphi非常好地处理COM对象,您可以从Delphi代码中轻松调用C#方法。
答案 4 :(得分:0)
使用线程池或IOCP代替?是的,它有点复杂和资源消耗,但不需要执行外部进程。新的ThreadPool API(Vista和更高版本)为您提供了更多的机会和灵活性(您甚至可以标记长时间运行的任务):