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

江枫思渺然 提交于 2019-11-27 19:33:42

问题


I am creating a GUI application using Visual C# 2005 (net framework 2). I use the following code to start a process:

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

I want my application to wait until this process is finished, so I used WaitForExit. But the GUI Windows freezes while app.exe is running. I want it to respond (e.g. press a cancel button), but I don't want the code to continue, because there is another process to start after than. Thanks in advance!


回答1:


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
}



回答2:


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.




回答3:


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



回答4:


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.




回答5:


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




回答6:


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


来源:https://stackoverflow.com/questions/1728099/visual-c-sharp-gui-stops-responding-when-process-waitforexit-is-used

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!