0

我目前正在处理 ac# 项目,并且正在使用 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));
        }
4

2 回答 2

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();
}
于 2012-04-20T16:34:16.677 回答
0

为什么要使用线程名称?如果您要将此活动集中起来,您将不知道哪个线程将运行任何特定进程。

如果您正在管理进程,请定义一个“managedProcess”类,该类可以包含进程名称、进程 EXE 路径、进程句柄、在句柄上等待进程完成的线程、任何状态枚举、要保留的任何互斥锁的字段和属性字段线程安全,启动和停止它的方法 - 与进程有关的任何事情。将此 managedProcess 类的实例推送到您的容器中。

恕我直言,忘记除调试以外的任何线程名称。

终止 - 在您的 stop() 方法中,您可以尝试发布 WM_CLOSE,(您可以直接执行此操作,还是 P/Invoke?),等待几秒钟以查看线程等待是否发出进程已关闭的信号并且,如果没有,请调用 TerminateProcess(),(或任何用于 TerminateProcess 的托管事物)。

于 2012-04-20T13:56:36.400 回答