Reputation: 1117
I'm looking for a fast alternative to CreateProcess in Delphi to execute certain calculations in an exe, including several return-values in XML. Currently, I'm calling an C#-exe with certain parameters. One of these calls takes approx. 0.5s - which is way to expensive, since this exe needs to be called a couple of hundred times (unfortunatley iterative calls, i.e. multithreading won't speed up the job).
My current code looks like this (found the solution to get the console output of the exe somwhere on StackOverflow).
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
Btw, I'm not very good a Delphi - actually, I kinda feel like the "I have no idea what I'm doing" dog-meme-thing...
Upvotes: 2
Views: 4672
Reputation: 2488
Use Thread Pools or IOCP instead? Yeah, it's a little bit complicated and resource consuming, but eliminates the need to execute external processes. The new ThreadPool APIs (Vista and later) give you much more opportunities and flexibility (you can even mark tasks that run for long time):
Upvotes: 0
Reputation: 24473
Like David wrote and André wrote, you cannot change this.
This is one of the really big differences between Windows and Linux. CreateProcess
in Windows is very expensive, whereas fork
in Linux is cheap. On the other hand, a Linux fork
is usually followed by an exec
which is expensive. This is why .NET introduced the AppDomain
which is faster.
There are a couple of directions you could go to integrate the .NET code into your process like Arnaud wrote.
Another thing you can do is do IPC between a Delphi process and a .NET process (for instance using named pipes), and have the .NET process use AppDomains for each request.
Upvotes: 3
Reputation: 43023
What is slow here is creating a new process, and much more launching the whole .Net framework process each time you run the execuable.
For best performance, you should better expose your C# process as COM, then call it from Delphi directly.
Remote connection via TCP/IP is not worth it in this case, I guess. I had bad speed experiment about using RemObjects in such case on a local machine, some years ago.
What you need is call COM interop, and you may be interested in:
Delphi handles COM objects very well, and you would be able to call C# methods very easily from Delphi code.
Upvotes: 1
Reputation: 9112
Do you need to create a new process every time? Or can you re-use the same instance? You can do it with some low level console input/output piping (your code looks like you're trying to do this now :) ), or you can use some kind of IPC (mutex+shared memory, to copy data between 2 processes), or you can use a more n-tier (or client/server) approach by communicating via TCP/IP (RemObjects SDK is very good for this one, has both .Net and Delphi libs, which communicate via TCP/IP, or windows messages, named pipes, etc). However the last approach adds some more delay/overhead because of the abstraction but is much easier to use than to implement both sides in .Net and Delphi yourself (it is not that difficult btw).
Upvotes: 3
Reputation: 612894
Creating a new process is expensive. There are no alternatives to using CreateProcess
. There are no quick fixes here. There's no magic button which makes process creation super fast.
The solution to your problem is going to be to stop creating a new process altogether. Perform this task inside your process.
Upvotes: 8