The program does not increase the progress bar while waiting for the stream to exit

I have a C # form application that serves as a user interface and runs an external exe. I want to increase the execution step until the external exe completes the execution. so i have the following code:

// create thread and Start external process Thread MyNewThread = new Thread(new ThreadStart(startmodule)); MyNewThread.Start(); do { if (progressBar1.Value < 100) { progressBar1.Value++; } } while (MyNewThread.IsAlive); label5.Text = "Status: Done"; // startmodule() void startmodule() { ProcessObj = new Process(); ProcessObj.StartInfo.FileName = ApplicationPath; ProcessObj.StartInfo.Arguments = ApplicationArguments; ProcessObj.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; ProcessObj.Start(); } 

Instead, it instantly fills the bar and displays the “Finish” message, but the external exe (AppPath) is still running in the background.

Please post some ideas that I'm stuck with. I do not know what happened. Thank you for your time.

+4
source share
6 answers

You cannot do this work, you cannot guess how long the process will take. Set the ProgressBar.Style property to Marquee. Set the Visible property to true when the process starts. Use the Process.Exited event to return false. Like this:

 public partial class Form1 : Form { public Form1() { InitializeComponent(); progressBar1.Style = ProgressBarStyle.Marquee; progressBar1.Visible = false; } private void ButtonRunProcess_Click(object sender, EventArgs e) { var ProcessObj = new Process(); ProcessObj.SynchronizingObject = this; ProcessObj.EnableRaisingEvents = true; ProcessObj.Exited += new EventHandler(ProcessObj_Exited); ProcessObj.StartInfo.FileName = @"c:\windows\notepad.exe"; // etc... ProcessObj.Start(); progressBar1.Visible = true; } void ProcessObj_Exited(object sender, EventArgs e) { progressBar1.Visible = false; } } 
+4
source

Well, the cycle runs so fast that it reaches 100% before your task is completed. The loop test condition (the thread being live) will be true until your task is completed, but the loop will cause the progress bar to fill ahead of schedule.

+4
source

To run a progress bar, you must be able to quantify the progress of a long-term task. You have nothing in the code that is trying to quantify this.

You will need a connection between the two processes for this progress indicator to work well. In other words, the external process needs to send messages back to the parent application, informing the parent application about the progress. This can now be difficult to achieve, so marquee style may be more appropriate.

+1
source

Finally, I got some “free” time to test the background worker, as suggested above. I can say that this is the best solution and it will not slow down the interface. The following is an example implementation:

 preparemodule() { ProcessObj = new Process(); ProcessObj.StartInfo.FileName = ApplicationPath; ProcessObj.StartInfo.Arguments = ApplicationArguments; } void run_Click(object sender, EventArgs e) { preparemodule(); backgroundWorker1.RunWorkerAsync(ProcessObj); } void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { int i=0; ProcessObj.Start(); while (checkifexists("notepad", 0) == true) { i++; label5.Text = "Status: notepad running... " + progressBar1.Value.ToString() + "%"; Thread.Sleep(3000); backgroundWorker1.ReportProgress(i); if ((backgroundWorker1.CancellationPending == true)) { e.Cancel = true; } } } void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { if (e.ProgressPercentage <= 100) { progressBar1.Value = e.ProgressPercentage; } } void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { label5.Text = "Status: Done"; } void cancel_Click(object sender, EventArgs e) { backgroundWorker1.CancelAsync(); } 

As you can see, we can even cancel it. and by checking if the notebook works, we can increase progress. Remember to include the bgWorker properties "reportsprogress" and "supportscancellation" somewhere in your code. I hope this helps someone.

+1
source

Firstly, @Tim's answer is right about what's happening.

If you can control an external application, lay down a way for it to communicate with the main process reporting the current state, and update the progress bar in accordance with these messages.

If this is not possible, try evaluating the lead time and set the progress according to the lead time. This is true if it performs the same time for the same task.

0
source

A background work thread has been designed for this kind of thing. It has an event that you can trigger when processing something, you process it and update your progress bar. Of course, as others have noted, you do not seem to have made any progress, some time has passed, so this is actually not an indicator of the progress you want, but some kind of animation “I'm busy” if you use progress bar for this you get all kinds of problems that lead the boys in the UI crazy, as if he never reaches 100%, or he gets to 100% long before the operation is completed or even cycles.

So, if you can indicate some kind of progress in the stream, for example, if you are looping over the elements of X, fire a progress event every 10% of X. Use the background thread. If you cannot use the progress bar, release the thread to make some animated control visible. When the thread ends, make the animation invisible again. What and how the animation is up to you and your boys from the UI.

0
source

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


All Articles