2

XML のいくつかの戻り値を含む、exe で特定の計算を実行するために、Delphi の CreateProcess に代わる高速な方法を探しています。現在、特定のパラメーターを使用して C#-exe を呼び出しています。これらの呼び出しの 1 つには、約 1 回かかります。0.5 秒 -この exe を数百回呼び出す必要があるため、コストがかかりすぎます (残念なことに、反復呼び出し、つまりマルチスレッドではジョブが高速化されません)

私の現在のコードは次のようになります (StackOverflow のどこかにある exe のコンソール出力を取得するソリューションが見つかりました)。

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 はあまり得意ではありません。

4

5 に答える 5

8

新しいプロセスの作成にはコストがかかります。を使用する以外に方法はありませんCreateProcess。ここには簡単な修正はありません。プロセスの作成を超高速にする魔法のボタンはありません。

問題の解決策は、新しいプロセスの作成を完全に停止することです。プロセス内でこのタスクを実行します。

于 2012-09-27T13:29:11.177 に答える
3

毎回新しいプロセスを作成する必要がありますか?または、同じインスタンスを再利用できますか?低レベルのコンソール入出力パイプでそれを行うことができます(コードは今これを行おうとしているように見えます:))、またはある種のIPC(mutex +共有メモリ、2つのプロセス間でデータをコピーするため)を使用できます)、またはTCP / IPを介して通信することでよりn層(またはクライアント/サーバー)のアプローチを使用できます(RemObjectsSDKはこれに非常に適しています。TCP/IPを介して通信する.NetライブラリとDelphiライブラリの両方があります。 Windowsメッセージ、名前付きパイプなど)。ただし、最後のアプローチでは、抽象化のために遅延/オーバーヘッドがいくらか追加されますが、.NetとDelphiで両方を自分で実装するよりもはるかに簡単に使用できます(それほど難しいことではありません)。

于 2012-09-27T13:57:46.970 に答える
3

David が書きAndré が書いたように、これを変更することはできません。

これは、Windows と Linux の大きな違いの1 つです。CreateProcessWindows では非常に高価ですがfork、Linux では安価です。一方、Linux のfork後には通常、exec高価な が続きます。これが、 .NETAppDomainがより高速な を導入した理由です。

Arnaud が書いたように、.NET コードをプロセスに統合するには、いくつかの方法があります。

もう 1 つの方法として、Delphi プロセスと .NET プロセスの間で IPC を実行し (たとえば、名前付きパイプを使用)、.NET プロセスでリクエストごとに AppDomains を使用することができます。

于 2012-09-27T17:04:59.367 に答える
1

ここで遅いのは、新しいプロセスを作成することであり、execuableを実行するたびに.NetFrameworkプロセス全体を起動することです。

最高のパフォーマンスを得るには、C#プロセスをCOMとして公開してから、Delphiから直接呼び出す必要があります。

この場合、TCP/IPを介したリモート接続は価値がないと思います。数年前、ローカルマシンでこのような場合にRemObjectsを使用することについて、速度の悪い実験をしました。

必要なのはCOM相互運用機能を呼び出すことであり、次のことに興味があるかもしれません。

DelphiはCOMオブジェクトを非常にうまく処理し、DelphiコードからC#メソッドを非常に簡単に呼び出すことができます。

于 2012-09-27T15:43:26.513 に答える
0

代わりにスレッド プールまたは IOCP を使用しますか? 少し複雑でリソースを消費しますが、外部プロセスを実行する必要がなくなります。新しい ThreadPool API (Vista 以降) により、より多くの機会と柔軟性が得られます (長時間実行されるタスクをマークすることもできます)。

于 2012-09-27T20:45:00.253 に答える