c# - 取消正在运行的进程

标签 c# asp.net multithreading process

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

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

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

并从 Progress 窗口表单关闭/中止进程:

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;
    }
}

正确的做法是什么?

最佳答案

两者的结合。

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() ,你应该无论如何避免,因为它会产生各种令人讨厌的副作用(例如,你将能够在递归中多次运行相同的代码).

关于c# - 取消正在运行的进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19658838/

相关文章:

c - 在 C 中创建目录的线程安全函数

Java 等待线程完成

c# - 在 Visual Studio 2010 语言服务中实现查找引用

c# - UWP 用户控件项目类型

c# - ScriptManager.RegisterStartupScript 未在 updatepanel 内第二次触发

c# - 如何在 SQL Server 2008 中的特定列中存储列值?

c# - ASP.NET 和 C# : MessageBox not shown when used in combination with Response. 重定向

asp.net - ASP MVC - 反转 foreach

c# - MVC4 捆绑缓存 header

Java "unstopped "执行/完成线程