Cancel a process while it starts

I run a process that executes exe on the command line with arguments, and it takes time to complete. In the meantime, I am showing the form as a dialog with a progress bar and a cancel button. When the cancel button is pressed, the process should be interrupted / stopped. I have two ways to do this:

a. Declare an open static object of the Process class in the main form and interrupt it from the execution form when you click the cancel button:

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

And close / abort the process from the execution window form:

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

B. Or do not call Process.WaitForExit (); and use Process.HasExited instead to check if the process is running and cancel it if the cancel button is clicked:

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

What is the right way to do this?

+6
source share
1 answer

The connection of the two.

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

And in the cancel handler

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

Of course, now you need to find a way out of the normal path. Use Process.HasExited regularly to poll to complete. It is best to use a timer for this. I'm not sure at the moment, but there might even be an event for this.

Your second solution has a problem that it is actively waiting for the process to complete, while still blocking the user interface. And it uses Application.DoEvents() , which you should avoid in every way, because it creates all kinds of unpleasant side effects (for example, you can have the same code several times in recursion).

+6
source

Source: https://habr.com/ru/post/956943/


All Articles