关闭通过线程启动的进程
本文关键字:启动 进程 线程 | 更新日期: 2023-09-27 18:31:42
我目前正在处理一个 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));
}
为什么要对任何内容使用线程名称? 如果要将此活动池化,您将不知道哪个线程将运行任何特定进程。
如果要管理进程,请定义一个"managedProcess"类,该类可以包含进程名称、进程 EXE 路径、进程句柄、等待句柄以完成进程的线程、任何状态枚举、任何保持字段线程安全、启动和停止它的方法的字段和属性 - 与进程有关的任何内容。 将此 managedProcess 类的实例推送到容器中。
恕我直言,忘记除调试之外的任何线程名称。
终止 - 在你的 stop() 方法中,你可以尝试发布一个WM_CLOSE(你可以直接这样做,还是一个 P/Invoke?),等待几秒钟,看看线程等待是否发出进程已经关闭的信号,如果没有,调用 TerminateProcess(),(或任何用于 TerminateProcess 的托管东西)。
除非您有通过使用单独的线程创建每个进程来解决的特定需求,否则不要使用线程。如果您正在寻找的只是在代码中标识给定进程的唯一方法,则可以使用为线程指定的名称作为字典中的标识符。
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();
}