Torbjörn Dahlgren
Torbjörn Dahlgren

Reputation: 111

VS Progress bar, what to do when 100%

This is the code i have to day. The problem is that the progressbar goes 0 to 30% in 1 sec.

    private void pictureBox1_Click(object sender, EventArgs e)
    {
        progressBar1.Value = 5;

        System.Diagnostics.Process.Start("c:/installer.exe").WaitForExit();
        progressBar1.Value = 10;


        System.Diagnostics.Process.Start("c:/installer2.exe");
    progressBar1.Value = 30;

 }
    }

I Want to add a "sleep" o "wait" after the progressbar1(´s)

Ps. I just want to clear one thing out, iam level 0 on coding in Visual studio. I started to do this yesterday.

Upvotes: 0

Views: 548

Answers (2)

Harald Coppoolse
Harald Coppoolse

Reputation: 30492

A few years ago you had to create a BackgroundWorker object that would do the job to keep your UI responsive.

Since a few years we have async-await that can do the job. An async-await function looks like synchronous code, but whenever it sees an await, the code stops until the task it is awaiting for is finished. Meanwhile the thread that awaits has time to do other things, like updating progress bars, or keeping the UI responsive. Once the Task that the thread was awaiting for has finished, the thread continues with the statement after the await.

The only thing you have to do to use async-await, is to declare your event handler async. After you've done that you can call other async functions and await for their result.

After you've started your process you can await Task.Delay(TimeSpan). During this method the main thread isn't doing anything, so it has time to do other UI stuff. After the delay is finished it can update the progressbar and see if the process is finished.

using System.Diagnostics;
private async void pictureBox1_Click(object sender, EventArgs e)
{
    // start the progress, don't wait until finished yet:
    var process1 = Process.Start("c:/installer.exe").WaitForExit();
    while (!process1.HasExited)
    {
        // process not finished yet, increase progress bar and wait a while
        this.progressBar1.Step();
        await Task.Delay(TimeSpan.FromSeconds(0.2);
    }

    // if here, process1 has finished: we are halfway:
    progressBar1.Value = (progressbar1.Minimum + progressBar1.Maximum)/2;

    // start process 2
    var process2 = Process.Start("c:/installer2.exe");
     while (!process2.HasExited)
    {
        // process not finished yet, increase progress bar and wait a while
        this.progressBar1.Step();
        await Task.Delay(TimeSpan.FromSeconds(0.2);
    }
    // both processes finished; full progressbar:
    this.progressBar1.Value = this.progressBar1.Maximum;
}

Of course you can have the problem that installing takes a long time. Consider not updating the progressbar anymore if the value becomes too high

var halfWay = (progressbar1.Minimum + progressBar1.Maximum)/2;
while (!process1.HasExited)
{
    if (this.progressBar1.Value < halfWay)
        this.progressBar1.Step();
    ...
}

Note that async await is done by one thread. It is not multi-tasking. Eric Lippert had a nice analogy on stackoverflow: async/await - Is this understanding correct?

Suppose you have to make breakfast. Toast some bread and cook some eggs.

  • Synchronous: start toasting bread. Wait until toasting finished. Start cooking eggs, wait until eggs are cooked.
  • Asynchronous but not concurrent: start toasting bread, and while the bread is toasting start cooking eggs. While the eggs are cooking yo can do other things, like making tea. After a while you wait until the eggs are cooked and wait until the bread is toasted. This is typically async-await.
  • Asynchronous and concurrent: hire a cook to toast the bread, hire a cook to cook the eggs and wait until both cooks are finished. Here the toasting and cooking is done by different threads. It is the most expensive method

Upvotes: 2

Schuere
Schuere

Reputation: 1649

use the code

System.Threading.Thread.Sleep(5000);

this will hold the current thread for 5 seconds.

HOWEVER: This will not change your current problem.

if I were you, i would look into backgroundworker. It's a little more trickier, but it can seriously help you. Your current thread get's updated while the backgroundworker thread can be halted. So then you receive a nice form in which the value get's updated. Also using the Sleep function is discouraged in the current thread.

Upvotes: 1

Related Questions