【问题标题】:Cancel a process while it is running取消正在运行的进程
【发布时间】:2013-10-29 12:55:54
【问题描述】:

我运行了一个进程,该进程在命令行中使用参数执行 exe,它需要一些时间才能完成。同时,我将表单显示为带有进度条和取消按钮的对话框。当按下取消按钮时,该过程应该中止/停止。我有两种方法:

A.在主窗体中声明 Process 类的公共静态对象,并在单击取消按钮时将其从进度窗体中止:

public partial class frmMain : Form
{
    public static Process Process = new Process();

    public static bool ExecuteCommand(string sCommandLineFile, string sArguments)
    {
        Process.StartInfo.FileName = sCommandLineFile;
        Process.StartInfo.Arguments = sArguments;
        Process.StartInfo.CreateNoWindow = true;
        Process.StartInfo.UseShellExecute = false;
        Process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

        Process.Start();
        Process.WaitForExit();
    }
}

并从进度窗口窗体关闭/中止进程:

public partial class frmProgress : Form
{
    private void btnCancel_Click(object sender, EventArgs e)
    {
        frmMain.Process.Close();
        frmMain.Process.Dispose();
    }
}

B.或者不要调用 Process.WaitForExit();而是使用 Process.HasExited 检查进程是否正在运行,如果单击取消按钮则取消它:

public static bool IsCancelled = false;

Process.StartInfo.FileName = sCommandLineFile;
Process.StartInfo.Arguments = sArguments;
Process.StartInfo.CreateNoWindow = true;
Process.StartInfo.UseShellExecute = false;
Process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

while (!Process.HasExited)
{
    Thread.Sleep(100);
    Application.DoEvents();

    if (IsCancelled)
    {
        Process.Close();
        Process.Dispose();
    }
}

public partial class frmProgress : Form
{
    private void btnCancel_Click(object sender, EventArgs e)
    {
        frmMain.IsCancelled = true;
    }
}

正确的做法是什么?

【问题讨论】:

    标签: c# asp.net multithreading process


    【解决方案1】:

    两者的混合。

    public partial class frmMain : Form
    {
        public static Process Process = new Process();
    
        public static bool ExecuteCommand(string sCommandLineFile, string sArguments)
        {
            Process.StartInfo.FileName = sCommandLineFile;
            Process.StartInfo.Arguments = sArguments;
            Process.StartInfo.CreateNoWindow = true;
            Process.StartInfo.UseShellExecute = false;
            Process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    
            Process.Start();
            // Process.WaitForExit(); // Don't wait here, you want the application to be responsive
        }
    }
    

    在取消处理程序中

    private void btnCancel_Click(object sender, EventArgs e)
    {
        frmMain.Process.Close(); // or .Kill()
        frmMain.Process.Dispose();
    }
    

    当然,现在您需要一种方法来查找进程是否已以正常方式退出。定期使用 Process.HasExited 轮询终止。最好为此使用计时器。我目前不确定,但甚至可能会为此举办活动。

    您的第二个解决方案的问题是它正在积极等待进程完成,同时仍然阻塞用户界面。它正在使用Application.DoEvents(),你应该避免使用它,因为它会产生各种讨厌的副作用(例如,你将能够在递归中多次运行相同的代码)。

    【讨论】:

    • 无需投票Process.HasExited 只需执行frmMain.Process.CanRaiseEvents = true 然后订阅Exited 事件。
    • 你的意思是frmMain.Process.EnableRaisingEvents = true(而不是CanRaiseEvents)?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多