关闭通过线程启动的进程

时间:2012-04-20 12:53:37

标签: c# multithreading system.diagnostics

我目前正在开发一个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));
        }

2 个答案:

答案 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();
}