4

ここで私の論理が正しいことを確認したいと思います。プロセスを数秒間実行したいのですがtimeout、それが長く実行されている場合は、すぐに強制終了する必要があります。

フラグはcompleted、プロセスが意図したとおりに完了したかどうかを確実に示す必要があります。

process.HasExitedまた、へのチェックが正しいかどうか、私は確信が持てません。process.WaitForExit()false を返し、Kill()成功した場合、process.HasExited 常にtrue になりますか? それは私の推測ですが、確認したかったのです。また、ログ記録以外に、Kill() が失敗した場合に何かできることがあるとしたら?

        using (process = new Process())
        {
            process.EnableRaisingEvents = true;
            process.OutputDataReceived += new DataReceivedEventHandler(OnOutputDataReceived);
            process.ErrorDataReceived += new DataReceivedEventHandler(OnErrorDataReceived); 
            process.Exited += new EventHandler(OnExited);

            process.StartInfo = startInfo;
            process.Start();

            process.BeginOutputReadLine();
            process.BeginErrorReadLine();

            if (!process.WaitForExit(timeout))
            {
                try
                {
                    process.Kill(); 
                }
                catch (Exception e)
                {
                    LogError(e, MethodBase.GetCurrentMethod());
                }
                finally
                {
                    this.completed = false;
                }
            }
            else
            {
                if (process.HasExited)
                {
                    this.code = process.ExitCode; 
                    this.completed = true;
                }
                else
                {
                    this.completed = false; 
                }
            }
        }
4

4 に答える 4

4

はい、HasExited は常に true になります。

MSDNによると、

" HasExited の true の値は、関連付けられたプロセスが正常終了または異常終了したことを示します。 [...]プロセスはコードとは無関係に終了できます。このコンポーネントを使用してプロセスを開始した場合、システムは HasExited の値を更新します。関連付けられたプロセスが個別に終了した場合でも、自動的に. "

ただし、タイムアウト前にプロセスがクラッシュして終了した場合、コードはそれを完了済みとして設定します。終了コードを確認する必要があるかもしれませんが、プロセスごとに異なる意味を持つ可能性があります。

if (process.ExitCode != 0)
{
    this.completed = false;
}

クラッシュについては、いくつかのアプローチがここここにありますが、通常、すべてのプロセスのクラッシュを検出することはできません。

于 2013-09-25T13:34:33.210 に答える
1

これを使用できます。これは、 JobObjects機能の C# ラッパーです。背後にあるアイデアは(私が言及したライブラリ内に埋め込まれている低レベルのアウトライン)です:

  1. ジョブ オブジェクトを作成します。
  2. 時間制限が x 秒になるようにジョブ オブジェクトを構成します。
  3. プロセスを作成し、それを再開する前にそれをジョブ オブジェクトに割り当てます。
  4. プロセスを再開します。
  5. 時間が経過すると、プロセスはオペレーティング システムによって強制終了されます。通常、0 以外のリターン コードまたはコールバックによって通知されます。JobObject API 自体はコールバックを許可しますが、C# ラッパーについては不明です。

また、ジョブ オブジェクトを使用すると、メモリ使用量を制限できます。私が言及したページでは、例も見つけることができます。

アップデート

上記のステートメントを書いた後、親プロセスが強制終了されたときにこの Kill child process を見つけました。彼らは別のタスクに JobObjects を使用しますが、JobObjects の使用法はあなたの場合と同じでなければなりません。

于 2013-10-01T17:11:21.173 に答える