我目前正在开发一个c#项目,并且正在使用System.Diagnostic.Process类。
当我的程序启动时,它会创建一个新线程,并在每个线程内启动一个不同的进程。
在某些时候,我需要检查程序中的设置,看看每个进程是否应该继续运行,或者是否应该停止但是我不知道如何引用某个线程启动的进程。每个线程在进程启动时都给出了一个名称,但我的理解是c#创建线程,启动进程然后关闭线程,即使进程仍在运行并且仍在接收输出。
有没有办法可以找出哪个进程是由哪个线程启动的,并取消该进程的运行。
但我无法看到如何使用此方法和字典能够根据此线程名称停止进程。
更新 下面的请求是我正在使用的代码,它在线程中创建每个进程。我在字典中使用该线程,以便我可以从outputreceived事件中引用它,但如果我需要关闭该进程,则不确定如何执行该操作。
Thread worker = new Thread(new ThreadStart(() => startProducts(product.Value[0].startScript, product.Value[0].productName)));
worker.IsBackground = false;
worker.Name = product.Value[0].productName;
worker.Start();
logging.logger(string.Format("Starting product '{0}'", product.Value[0].productName));
线程调用的方法如下,这是每个进程启动的位置。保证每个进程都有一个不同的命名线程,永远不会有两个具有相同名称的线程。
private void startProducts(string startScript, string product)
{
Process startProductProcess = new Process();
startProductProcess.StartInfo.FileName = startScript;
if ( configManagement.productConfig[product][0].requireArguments == true )
{
startProductProcess.StartInfo.Arguments = configManagement.productConfig[product][0].arguments;
}
startProductProcess.StartInfo.UseShellExecute = false;
startProductProcess.StartInfo.RedirectStandardOutput = true;
StringBuilder processOutput = new StringBuilder("");
startProductProcess.OutputDataReceived += new DataReceivedEventHandler(startProductProcess_OutputDataReceived);
startProductProcess.Exited += new EventHandler(startProductProcess_Exited);
processTag.Add(startProductProcess, product);
startProductProcess.Start();
//Process localByName = Process.GetProcessById(startProductProcess.Id);
startProductProcess.BeginOutputReadLine();
logging.logger(string.Format("Started {0} with: {1} {2}", product,
startProductProcess.StartInfo.FileName, startProductProcess.StartInfo.Arguments));
}
答案 0 :(得分:0)
为什么要使用线程名称?如果您要关闭此活动,您将不知道哪个线程将运行任何特定进程。
如果您正在管理进程,请定义一个'managedProcess'类,它可以包含进程名称的字段和属性,进程EXE路径,进程句柄,等待进程处理的线程,任何状态枚举,任何mutex保持字段线程安全,启动它并停止它的方法 - 与进程有关的任何事情。将此managedProcess类的实例推送到容器中。
恕我直言,除了调试之外,别忘了线程名称。
终止 - 在你的stop()方法中,你可以尝试发布WM_CLOSE,(你可以直接这样做,还是P / Invoke?),等待几秒钟,看看线程等待是否表示该进程已关闭,如果没有,则调用TerminateProcess(),(或者任何托管的东西都是TerminateProcess)。
答案 1 :(得分:0)
除非您通过使用单独的线程创建每个进程来解决特定需求,否则请勿使用线程。如果您要查找的只是识别代码中给定进程的唯一方法,则可以使用 给予该主题的名称作为字典中的标识符。
Dictionary<string, Process> processesByName = new Dictionary<string, Process>();
Process firstProcess = ... //Start your process
Process secondProcess = ... //Start your process
processesByName.Add("FirstProcessName", firstProcess);
processesByName.Add("SecondProcessName", secondProcess);
之后,您可以按照您指定的名称拉出一个给定的流程,然后根据需要与其进行交互。
Process process = processesByName["FirstProcessName"];
if (!process.HasExited)
{
process.CloseMainWindow();
process.Close();
}