2013-10-29 66 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)事件。 –