Visual C# GUI stops responding when process.WaitForExit(); is used

我是研究僧i 提交于 2019-11-28 14:11:13

You can capture the Exited event of the Process class:

void someMethod()
{
    //...possibly more code here
    Process process = new Process();
    process.StartInfo = new ProcessStartInfo("app.exe");
    process.StartInfo.WorkingDirectory = "";
    process.StartInfo.Arguments = "some arguments";
    process.Exited += new EventHandler(ProcessExited);
    process.Start();
}

void ProcessExited(object sender, System.EventArgs e)
{
  //Handle process exit here
}

Your waiting for the process on the only thread of your application that is also responsible for handling all GUI events. If you want to wait for some event (like some other process to finish) and still have your code notified of the event then you have to wait on another thread or use an event handler.

This should help. Basically for windows forms and simple tasks like this, a BackgroundWorker is handy. Below is some simple code to launch notepad and wait for it to either close or the user can kill it by clicking cancel.

    public Form1()
    {
        InitializeComponent();
        backgroundWorker1.WorkerSupportsCancellation = true;
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        Process process = new Process();
        process.StartInfo = new ProcessStartInfo("notepad.exe");
        process.Start();
        while (!process.HasExited)
        {
            if (backgroundWorker1.CancellationPending)
            {
                process.Kill();
                continue;
            }
            else
                Thread.Sleep(1000);
        }
    }

    private void Start_Click(object sender, EventArgs e)
    {
        backgroundWorker1.RunWorkerAsync();
    }

    private void Cancel_Click(object sender, EventArgs e)
    {
        backgroundWorker1.CancelAsync();
    }

In order to receive a callback on Exited event, the EnableRaisingEvents must be set to true.

Process correctionProcess = Process.Start(startInfo);
correctionProcess.EnableRaisingEvents = true;
correctionProcess.Exited += new EventHandler(ProcessExited); 

Using exited worked well for me and gave me great flexibility to either run sequentially, partially concurrently, or all at once - without locking the UI.

Nikos Steiakakis

Perhaps you should implement a solution with the BackgroundWorker. It is easy to implement and does what you want.

What you have to do is add an instance of a BackgroundWorker in your form, and make the call to the Process running the App.exe from the BackgrondWorker RunWorkerAsync method. Then on you can monitor for a CancelationPending property to stop the process or RunWorkerCompleted event to perform whatever is necessary after the Process has exited.

There is another SO question, concerning the BackgroundWorker cancelation

the solution for this is using a multi-threading start by adding:

using System.Threading;

then look at the code bellow :

    Process process = new Process();
    process.StartInfo = new ProcessStartInfo("app.exe");
    process.StartInfo.WorkingDirectory = "";
    process.StartInfo.Arguments = "some arguments";

//starts a new thread that starts the process so when you call WaitForExit it does not freez the main thread

    Thread th= new Thread(() =>
    {
        process.Start();
        process.WaitForExit();
    });
    th.Start();

if you want to run multiple process back to back it is another case you will need to use something like a List of process look at the code bellow

    List<Process> processes = new List<Process>();;

    Process process = new Process();
    process.StartInfo = new ProcessStartInfo("app.exe");
    process.StartInfo.WorkingDirectory = "";
    process.StartInfo.Arguments = "some arguments";

    processes.Add(process); 

// i add another one manually but you can use a loop for exemple

    Process process2 = new Process();
    process.StartInfo = new ProcessStartInfo("app.exe");
    process.StartInfo.WorkingDirectory = "";
    process.StartInfo.Arguments = "some arguments";

    processes.Add(process2);

// then you will start them though your thread and the 2nd process will wait till the first finishes without blocking the UI

    Thread th= new Thread(() =>
    {
            for (int i = 0; i < processes.Count; i++)
            {
                    processes[i].Start();
                    processes[i].WaitForExit();
             }
    });
    th.Start();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!