私のコードでは説明できない動作が検出されていますが、正常に動作していても、本当に私を悩ます。 以下のスクリプトは、n_total
のメモ帳のプロセスを作成して実行しますが、毎回最大n_cpus
のメモ帳しか実行できません。最初に、n_cpus
プロセスが起動され、残りの1つ以上の実行中のメモ帳が終了すると、残りのプロセスが開始されます。各メモ帳プロセスは、コード内のProcess.Exitedイベントをトリガーするウィンドウを閉じるだけで、ユーザーが終了することができます。今度は、ループ内で、変数p
を再利用して、新しいメモ帳が必要になるたびにプロセスProcessクラスをインスタンス化します。p.Exited += p_Exited;
n_cpus = 3
があるとします。それらの3つの同時メモ帳を生成します。私は、p
とp.Exited
がオブジェクトに属していますが、最後のインスタンスp
だけがイベントを発生させることを期待しています...どのメモ帳を閉じてもイベントは発生し、新しいメモ帳が表示されます。どうしたの?作成するすべてのプロセスを記憶している代理人EventHandlerのオブジェクトレスリストがありますか?イベントProcess.Exitedは、whileループで再インスタンス化した後のオブジェクトの寿命を延ばします
using System;
using System.Diagnostics;
using System.Threading;
class Program
{
// Summary: generates processes for "n_total" notepads allowing for a maximum of "n_cpus"
// notepads at each time. Every time a notepad closes another appears until all are run.
// A single variable "p" instantiates the class "Process" and the event "p.Exited"
// updates the number of running processes "n_running".
static int n_running = 0; // number of notepads running each time
static void Main()
{
int n_cpus = 3;
int n_total = 3 * n_cpus;
int i_run = 0;
while (i_run < n_total) // Process generating routine until all are run
{
if (n_running < n_cpus) // Only a maximum of n_cpus running at each time
{
n_running++;
i_run++;
Process p = new Process(); // A new object per process
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c notepad.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.EnableRaisingEvents = true;
p.Exited += p_Exited; // Is this associated with a particular object "p", right?
p.Start();
}
else Thread.Sleep(1000); // Waits 1s before checking for new terminated processes
}
}
static private void p_Exited(object sender, EventArgs e)
{
n_running--; // Updates the number of active processes. Triggers new future processes
}
}
新しいプロセスを作成し、それを設定してイベントを発生させ、イベントをサブスクライブして出口に通知します。あなたがそれを求めたときにすべてが機能します。 – Jimi
Cmd.exeの使用が正しくない、コンソールモードプロセスを開始するときだけブロックします。 'cmd.exe/c start/wait notepad.exe'を使う必要があります。しかし、cmd.exeを使わずにNotepad.exeを直接起動するほうが簡単です。もう一つのバグを修正してください。intはSemaphoreSlimに代わる適切なものではありません。 –
@Hans興味深いことに、SemaphoreSlimクラスについては、このケースでは適切であるように見えますが、もっと詳しく読む必要があります。今度は 'cmd.exe'のために、これは実際にcmdから起動されなければならない別のexeファイルです(あるいは少なくとももっと便利な方法です)。しかし、あなたが提案する 'start/wait'の変更は、アプリケーションがコマンドラインから起動され、コマンドスクリプトから起動されない場合にのみ変化します。換言すれば、それは常にメモ帳が閉じるのを待つ。 **プログラムの実行**:[link](https://ss64.com/nt/start.html) – epp