2013-10-29 65 views
6

我运行了一个进程,该进程在带有参数的命令行中执行一个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; 
    } 
} 

什么是做正确的方式?

回答

6

两者的混合。

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(),你应该尽量避免它,因为它会产生各种令人讨厌的副作用(例如,你可以在递归中运行多次相同的代码)。

+0

无需轮询'Process.HasExited'只需执行'frmMain.Process.CanRaiseEvents = true',然后订阅[Exited](https://msdn.microsoft.com/en-us/library/system.diagnostics .process.exited(v = vs.110).aspx)事件。 –