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

后端 未结 6 1792
臣服心动
臣服心动 2020-12-12 01:14

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         


        
相关标签:
6条回答
  • 2020-12-12 01:24

    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();
    
    0 讨论(0)
  • 2020-12-12 01:27

    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.

    0 讨论(0)
  • 2020-12-12 01:33

    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
    }
    
    0 讨论(0)
  • 2020-12-12 01:39

    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.

    0 讨论(0)
  • 2020-12-12 01:41

    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();
        }
    
    0 讨论(0)
  • 2020-12-12 01:43

    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

    0 讨论(0)
提交回复
热议问题