【问题标题】:System.Diagnostics.Process.Kill doesn't work properly. C#System.Diagnostics.Process.Kill 无法正常工作。 C#
【发布时间】:2015-02-04 02:29:21
【问题描述】:

我有WinForm (.NET 4.5 C#) 应用程序,我有BackgroundWorker,我使用下面的代码从它开始新的Process

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker bw = sender as BackgroundWorker;

        string fileName_ = e.Argument.ToString();

        Process myProcess = new Process();
        int exitCode = 0;

        try
        {
            if (!File.Exists(fileName_))
            {
                throw new FileNotFoundException("Failed to locate " + fileName_);

            }


            #region Start Info:
            ProcessStartInfo startInfo = new ProcessStartInfo(fileName_);
            startInfo.UseShellExecute = false;
            startInfo.CreateNoWindow = true;
            startInfo.RedirectStandardOutput = true;
            startInfo.RedirectStandardError = true;

            myProcess.StartInfo = startInfo; 
            #endregion

            myProcess.Start();
            StreamReader myStreamReader = myProcess.StandardOutput;

            while (!myProcess.HasExited)
            {
                myProcess.Refresh();
                string output = myStreamReader.ReadLine();
                bw.ReportProgress(0, output);

                if (bw.CancellationPending)
                {
                    myStreamReader.ReadToEnd();
                    myStreamReader.Close();

                    myProcess.StandardError.ReadToEnd();
                    myProcess.StandardError.Close();
                    myProcess.Kill();
                    break;

                }

            }


            //myProcess.WaitForExit();


            bw.ReportProgress(0, string.Format("Process {0}  exit code: {1}", fileName_, myProcess.ExitCode));

            exitCode = myProcess.ExitCode;
            if (exitCode != 0 && !bw.CancellationPending)
            {
                string error = myProcess.StandardError.ReadToEnd();


                myProcess.Close();
                myProcess = null;

                bw.ReportProgress(0, "Process Failed with message:" + Environment.NewLine + error);
            }

            myProcess.Close();

        }
        catch (Exception ex)
        {                

            Console.WriteLine(ex);

        }
        finally
        {
            myProcess.Dispose();
            myProcess = null;

        }

        e.Result = exitCode;
    }

这部分工作正常,但是一旦我尝试使用myProcess.Kill();后台工作人员停止并且一切正常,但我可以看到我的进程仍在从任务管理器运行,即使我关闭我的应用程序,我仍然可以在任务管理器中看到我的进程正在运行。

我的问题是,如何正确终止进程?

我希望我清楚地描述了我的问题,如果您需要更多信息,请随时告诉我。

任何帮助将不胜感激。

//-------------2014 年 12 月 8 日更新 ---------//

@RogerN 我删除了 Process.WaitForExit() 并添加了 myStreamReader.ReadToEnd() 相同的问题进程即使在应用程序关闭后仍然存在。

@phillip 这是我从 WinForm 调用的控制台应用程序(独立 *.exe)。

@Peter Duniho 是的,我确信它在任务管理器中是相同的过程。删除 WaitForExit() 并没有解决任何问题,BW 实际上完成得很好,没有任何问题。

@L.B 你会建议什么替代方案?

【问题讨论】:

  • 它是什么类型的进程?如果它是一个服务,那么你的答案与它是一个独立的 exe 不同。
  • 您确定您在任务管理器中看到的进程是您启动的进程吗?您的 BW 代码在它启动然后终止的进程上调用 WaitForExit(),但您声称 BW 实际上已完成。因此,代码与您所说的发生了一些矛盾。
  • 您是否以管理员身份运行程序?
  • 提示:如果你发现自己在写一个忙着等待的代码,比如 while (!myProcess.HasExited)while (someTask.IsAlive)while (someSource.DataAvailable) ,请确保你走错了方向。

标签: c# .net winforms backgroundworker system.diagnostics


【解决方案1】:

可能会发生死锁,因为您在读取整个输出流之前调用 Process.WaitForExit()。由于您已重定向输出流,因此您必须先从关联流中读取所有数据,然后才能正常退出进程。

【讨论】:

  • 这是普通的控制台可执行文件,我删除了 Process.WaitForExit() 仍然是同样的问题。是的,我确信这与我的任务管理器中的过程相同。我试图以管理员和普通用户的身份运行同样的问题。你打算用什么来代替 while 循环?
  • 由于您正在重定向标准输出和标准错误流,因此您需要确保在进程退出之前读取到两个流的末尾。在上面的 while 循环中,您只读取标准输出,而不是标准错误流,因此该进程可能永远不会正常退出。
  • 我更新了 while 循环(参见我的第一篇文章中的代码),关闭应用程序后相同的问题过程仍然存在。应该还有其他问题。也许我设置 ProcessStartInfo 不正确?
  • 好的,我想我明白了,它与这个特定的 *.exe 文件有关,不确定到底是什么,但我尝试使用不同的控制台 *.exe 并且它工作正常。单击取消后退出。不知道下一步该做什么,因为我确实需要运行那个特定的控制台应用程序。如果有人有提示或建议,我将不胜感激。
  • myStreamReader.ReadLine() 可能会阻塞执行
猜你喜欢
  • 2011-08-31
  • 2020-08-01
  • 2013-08-26
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多